建立项目步骤:
c#桌面端窗体应用
命名为:transpart
创建两个label一个panel,以及一个按钮。
设计器中应该是这样才对:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace transpart
{
public partial class form1 : Form
{
Thread movel1, movel2;
bool run = false;//线程行标志
public form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
movel1 = new Thread(new ParameterizedThreadStart(sport));
movel2 = new Thread(new ParameterizedThreadStart(sport));
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "开始")
{ // 点击“开始”按钮时
run = false;
if (movel1.ThreadState == ThreadState.Unstarted && movel2.ThreadState == ThreadState.Unstarted)
{
movel1.Start(label1);// 启用“圆点”线程
movel2.Start(label2); // 启用“五角星”线程
}
else
{
movel1.Resume();
movel2.Resume();
}
button1.Text = "暂停"; // 按钮中的字体内容替换为“暂停”
}
else if (button1.Text == "暂停")
{ // 点击“停止”按钮时
//run = true;
movel1.Suspend();
movel2.Suspend();
button1.Text = "开始"; // 按钮中的字体内容替换为“开始”
}
}
private void form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (movel1 != null)
movel1.Abort();
if (movel2 != null)
movel2.Abort();
}
public void sport(object lbl)
{
int px = panel1.Width - ((Label)lbl).Width; // 横向最大边界
int py = panel1.Height - ((Label)lbl).Height; // 纵向最大边界
int xadd = 1, yadd = 1; // 坐标偏移量
while (true)
{
int x = ((Label)lbl).Location.X; // 获取横坐标
int y = ((Label)lbl).Location.Y; // 获取纵坐标
if (x <= 0 || x >= px)
{// 判断是否到达边界
xadd *= -1;// 换方向
}
if (y <= 0 || y >= py)
{
yadd *= -1;
}
((Label)lbl).SetBounds(x + xadd, y + yadd, ((Label)lbl).Width, ((Label)lbl).Height);// 重新设置位置
try
{
Thread.Sleep(8); // 利用线程的休眠控制图标的运行速度
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
执行效果:
优化后:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace transpart
{
public partial class form1 : Form
{
private CancellationTokenSource cancellationTokenSource1;
private CancellationTokenSource cancellationTokenSource2;
private Task task1, task2;
public form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 初始化取消令牌
cancellationTokenSource1 = new CancellationTokenSource();
cancellationTokenSource2 = new CancellationTokenSource();
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "开始")
{
// 启动任务
cancellationTokenSource1 = new CancellationTokenSource();
cancellationTokenSource2 = new CancellationTokenSource();
task1 = Task.Run(() => sport(label1, cancellationTokenSource1.Token));
task2 = Task.Run(() => sport(label2, cancellationTokenSource2.Token));
button1.Text = "暂停";
}
else if (button1.Text == "暂停")
{
// 取消任务
cancellationTokenSource1.Cancel();
cancellationTokenSource2.Cancel();
button1.Text = "开始";
}
}
private void form1_FormClosing(object sender, FormClosingEventArgs e)
{
// 确保在关闭窗口时取消任务
cancellationTokenSource1.Cancel();
cancellationTokenSource2.Cancel();
}
public void sport(Label lbl, CancellationToken token)
{
int px = panel1.Width - lbl.Width; // 横向最大边界
int py = panel1.Height - lbl.Height; // 纵向最大边界
int xadd = 1, yadd = 1; // 坐标偏移量
while (!token.IsCancellationRequested)
{
int x = lbl.Location.X; // 获取横坐标
int y = lbl.Location.Y; // 获取纵坐标
if (x <= 0 || x >= px)
{
xadd *= -1; // 换方向
}
if (y <= 0 || y >= py)
{
yadd *= -1;
}
// 使用Invoke在UI线程更新位置
lbl.Invoke((Action)(() =>
lbl.SetBounds(x + xadd, y + yadd, lbl.Width, lbl.Height)));
Thread.Sleep(8); // 利用线程的休眠控制图标的运行速度
}
}
}
}