除停止按钮外,一切正常。 (按钮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”类型的异常,但未在用户代码中处理 附加信息:操作已取消。
解决:
循环时使用。谢谢!
答案 0 :(得分:0)
答案 1 :(得分:0)
正如@Roman所说,
如果在不同的任务中请求了令牌,则应为每个println "${mainUrl}${it.replaceAll('\\s','%')}/config.xml"
创建一个新的CancellationTokenSource
。
CancellationToken
制作两个不同的CancellationTokenSource cancellationTokenSource1, cancellationTokenSource2;
CancellationToken token1, token2;
和CancellationTokenSource
。
在for循环或while循环中使用它们,如下所示,具体取决于您的取消情况。
CancellationToken
或者
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);
}
答案 2 :(得分:0)
检查令牌是否被取消的部分应放在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应包含取消令牌的代码 cancellationTokenSource.Cancel();
对于按钮3和4,您需要不同的CancellationTokenSource和CancellationToken。