// 定义一个ManualResetEvent实例m,用于跨线程的信号传递
ManualResetEvent manualResetEvent;
// 定义一个CancellationTokenSource实例TokenSource,用于创建和管理CancellationToken
CancellationTokenSource TokenSource;
// 定义一个CancellationToken实例CancellationToken,它用于通知任务应该取消
CancellationToken CancellationToken;
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;// 禁用对非法跨线程调用的检查
}
private void button1_Click(object sender, EventArgs e)
{
// 创建一个新的CancellationTokenSource实例
TokenSource = new CancellationTokenSource();
// 从TokenSource中获取CancellationToken
CancellationToken cancellationToken = TokenSource.Token;
// 创建一个新的ManualResetEvent实例,并初始化为已信号状态(即允许等待的线程继续执行)
manualResetEvent = new ManualResetEvent(true);
// 使用Task.Factory启动一个新的任务,并传入一个lambda表达式作为任务的入口点
new System.Threading.Thread(() =>
{
for (int i = 0; i < 1000; i++)
{
// 检查是否请求了取消
if (cancellationToken.IsCancellationRequested)
{
// 如果请求了取消,则退出循环并结束任务
return;
}
// 等待m变为已信号状态
manualResetEvent.WaitOne();
// 在此处尝试更新textBox1的Text属性(但这是一个线程不安全的操作)
// 使用Control.Invoke来在UI线程上安全地更新UI元素
if (textBox1.InvokeRequired)
{
textBox1.Invoke((MethodInvoker)delegate {
textBox1.Text = i.ToString();
});
}
else
{
// 仅在textBox1已经在当前线程(这通常不会发生)时直接更新
textBox1.Text = i.ToString();
}
// 线程休眠500毫秒
System.Threading.Thread.Sleep(50);
}
}).Start(); // 传入cancellationToken以便在需要时取消任务
}
private void button2_Click(object sender, EventArgs e)
{
// 将m重置为非信号状态,这会导致任何正在等待m的线程被阻塞
manualResetEvent.Reset();
}
private void button3_Click(object sender, EventArgs e)
{
// 将m设置为已信号状态,允许任何正在等待m的线程继续执行
manualResetEvent.Set();
}
private void button4_Click(object sender, EventArgs e)
{
// 请求取消由TokenSource管理的所有任务
TokenSource.Cancel();
//TokenSource.CancelAfter(1000);延迟关闭
textBox1.Text = "";
}
驾驭C#多线程的魔法棒:掌握启动、暂停、继续、关闭线程
最新推荐文章于 2024-08-29 21:18:17 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)