[英]No effect on button click in multithreaded application
除停止按鈕外,一切正常。 (按鈕3和按鈕4 OnClick):
我制作了一個具有四個按鈕的應用程序。
它是一個多線程應用程序。
按鈕1和2將開始生成線程。
按鈕3和4將分別停止該過程。
但這似乎不起作用。
這是我的代碼:
public partial class Form1: Form
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken token;
public Form1()
{
InitializeComponent();
token = cancellationTokenSource.Token;
}
private void button1_Click(object sender, EventArgs e)
{
Task t = Task.Run(() =>
{
while (true)
{
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(1000);
Action act = () => textBox1.Text = Convert.ToString(i);
textBox1.Invoke(act);
}
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
}
}, token);
}
private void button2_Click(object sender, EventArgs e)
{
//token.Cancel();
}
private void button3_Click(object sender, EventArgs e)
{
Task t1 = Task.Run(() =>
{
while (true)
{
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(1000);
Action act = () => textBox2.Text = Convert.ToString(i);
textBox2.Invoke(act);
}
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
}
}, token);
}
private void button4_Click(object sender, EventArgs e)
{
//token.Cancel();
}
}
更新
這是更新的代碼:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiThreading_Start_Stop_Counter
{
public partial class Form1 : Form
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken token;
CancellationTokenSource cancellationTokenSource1 = new CancellationTokenSource();
CancellationToken token1;
public Form1()
{
InitializeComponent();
token = cancellationTokenSource.Token;
token1 = cancellationTokenSource1.Token;
}
private void button1_Click(object sender, EventArgs e)
{
Task t = Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
// your code
System.Threading.Thread.Sleep(1000);
Action act = () => textBox1.Text = Convert.ToString(i);
textBox1.Invoke(act);
}
});
}
private void button2_Click(object sender, EventArgs e)
{
cancellationTokenSource.Cancel();
}
private void button3_Click(object sender, EventArgs e)
{
Task t1 = Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
if (token1.IsCancellationRequested)
{
token1.ThrowIfCancellationRequested();
}
// your code
System.Threading.Thread.Sleep(1000);
Action act = () => textBox2.Text = Convert.ToString(i);
textBox2.Invoke(act);
}
});
}
private void button4_Click(object sender, EventArgs e)
{
cancellationTokenSource1.Cancel();
}
}
}
現在,任務正在取消,但有以下例外:
mscorlib.dll中發生類型'System.OperationCanceledException'的異常,但未在用戶代碼中處理。其他信息:操作已取消。
解決了:
用於while循環。 謝謝!
就像@Roman所說的那樣,
如果在不同的任務中請求令牌,則應該為每個CancellationToken
創建一個新的CancellationTokenSource
。
CancellationTokenSource cancellationTokenSource1, cancellationTokenSource2;
CancellationToken token1, token2;
制作兩個不同的CancellationTokenSource
和CancellationToken
。
根據您的取消情況,在如下所示的for循環或while循環中使用它們。
for (int i = 0; i < 100; i++)
{
if (token1.IsCancellationRequested)
{
token1.ThrowIfCancellationRequested();
}
// your code
System.Threading.Thread.Sleep(1000);
Action act = () => textBox1.Text = Convert.ToString(i);
textBox1.Invoke(act);
}
要么
while (token1.IsCancellationRequested)
{
}
檢查令牌是否已取消的部分應放在for循環內。
for (int i = 0; i < 100; i++)
{
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
System.Threading.Thread.Sleep(1000);
Action act = () => textBox1.Text = Convert.ToString(i);
textBox1.Invoke(act);
}
另外,您拋出OperationCanceledException並沒有捕獲它。
如果您不想處理該異常,則可以為while循環引入一些變量,例如:
Task t = Task.Run(() =>
{
var run = true;
while (run)
{
for (int i = 0; i < 100; i++)
{
if (token.IsCancellationRequested)
{
run = false;
break;
}
//loop code
}
}
}, token);
button2應該包含用於取消令牌的代碼cancelTokenSource.Cancel ();。
並且您需要按鈕3和4的不同的CancellationTokenSource和CancellationToken。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.