我有两个按钮,点击开始按钮会创建一个线程执行一个方法,方法运行一段时间,在结束前会修改界面上的值。
点击取消按钮会调用CancelTokenSource.Cancel();来取消线程。现在出现的问题是,我点击开始-停止-开始后,CancelTokenSource被重置了,第一个本来该取消的线程,读信号时认为不会取消,就又会改变界面上的值,导致错误的结果。请问怎么能记住这个线程被取消过呢?简化的过程代码如下:
public CancellationTokenSource CancelTokenSource;bool isCancel;
private void buttonStart_Click(object sender, EventArgs e)
{
isCancel = false;
CancelTokenSource = new CancellationTokenSource();
Task task = Task.Factory.StartNew(() =>
{
Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 启动了一个线程
IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}"); Thread.Sleep(10000); Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 10s后看状态
IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}"); }, CancelTokenSource.Token);
}private void buttonCancel_Click(object sender, EventArgs e)
{
CancelTokenSource.Cancel(); isCancel = true;
}
我点击开始-取消-开始。 创建一个线程后,取消线程,再创建一个线程。结果显示第一个线程的取消状态被重置了。
id=10 启动了一个线程 IsCancellationRequested=False isCancel=False
id=11 启动了一个线程 IsCancellationRequested=False isCancel=False
id=10 10s后看状态 IsCancellationRequested=False isCancel=False //想要的结果是true
id=11 10s后看状态 IsCancellationRequested=False isCancel=False
点击取消按钮会调用CancelTokenSource.Cancel();来取消线程。现在出现的问题是,我点击开始-停止-开始后,CancelTokenSource被重置了,第一个本来该取消的线程,读信号时认为不会取消,就又会改变界面上的值,导致错误的结果。请问怎么能记住这个线程被取消过呢?简化的过程代码如下:
public CancellationTokenSource CancelTokenSource;bool isCancel;
private void buttonStart_Click(object sender, EventArgs e)
{
isCancel = false;
CancelTokenSource = new CancellationTokenSource();
Task task = Task.Factory.StartNew(() =>
{
Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 启动了一个线程
IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}"); Thread.Sleep(10000); Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 10s后看状态
IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}"); }, CancelTokenSource.Token);
}private void buttonCancel_Click(object sender, EventArgs e)
{
CancelTokenSource.Cancel(); isCancel = true;
}
我点击开始-取消-开始。 创建一个线程后,取消线程,再创建一个线程。结果显示第一个线程的取消状态被重置了。
id=10 启动了一个线程 IsCancellationRequested=False isCancel=False
id=11 启动了一个线程 IsCancellationRequested=False isCancel=False
id=10 10s后看状态 IsCancellationRequested=False isCancel=False //想要的结果是true
id=11 10s后看状态 IsCancellationRequested=False isCancel=False
线程一调用cts.Cancel后,再new cts传给二不会影响到线程一,这样线程一在结束前还能知道它被Cancel过...测试发现好像还是同一个已解决,代码如下
private void buttonStart(object sender, EventArgs e)
{
cts = new CancellationTokenSource(); Task task = Task.Factory.StartNew(() =>
{
bool isCancel = false;
cts.Token.Register(() => isCancel = true); Console.WriteLine($"启动了一个线程 id={Thread.CurrentThread.ManagedThreadId} cts={cts.IsCancellationRequested} isCancel={isCancel}"); Thread.Sleep(10000); Console.WriteLine($"10s后查看状态 id={Thread.CurrentThread.ManagedThreadId} cts={cts.IsCancellationRequested } isCancel={isCancel}");
}
, cts.Token);
}
打印结果如下:
启动了一个线程 id=12 cts=False isCancel=False
启动了一个线程 id=13 cts=False isCancel=False
10s后查看状态 id=12 cts=False isCancel=True
10s后查看状态 id=13 cts=False isCancel=False
很明显不能在startNew中获取是否取消标识。toke通知任务取消,内部再怎么获取也是false。