c#-在任务执行代码时尝试处置任务
当“worker”正在执行一段代码时,我正在关闭整个窗口,我想在关闭该窗口时处理它,因为它正在完成它的代码c#-在任务执行代码时尝试处置任务,c#,C#,当“worker”正在执行一段代码时,我正在关闭整个窗口,我想在关闭该窗口时处理它,因为它正在完成它的代码 Task worker = Task.Factory.StartNew(new Action(() => { // some code here } 不幸的是,当我在Close()中调用worker.Dispose()时,出现了一个异常: 只有在任务处于完成状态时,才能对其进行处理 (RANTO完成、故障或取消) 有什么建议可以在它工作时处理吗?尝试使用取消令牌 var
Task worker = Task.Factory.StartNew(new Action(() =>
{
// some code here
}
不幸的是,当我在Close()
中调用worker.Dispose()
时,出现了一个异常:
只有在任务处于完成状态时,才能对其进行处理
(RANTO完成、故障或取消)
有什么建议可以在它工作时处理吗?尝试使用取消令牌
var cancellationTokenSource = new CancellationTokenSource();
var t = Task.Factory.StartNew(() =>
{
// Your code here
}, cancellationTokenSource.Token).ContinueWith(task =>
{
if (!task.IsCompleted || task.IsFaulted)
{
// log error
}
}, cancellationTokenSource.Token);
将cancellationTokenSource放在手边,并在关闭()时取消它。您需要编写代码,以便您的任务将接受取消令牌。这基本上只是一个可以由任务中的代码检查的标志,如果更新,您将提供要处理的逻辑,让任务的逻辑安全地处理如何终止其执行,而不是简单地在未知状态下停止。在LinqPad中运行以下示例代码应该可以为您提供一个合理的示例:
void Main()
{
var form = new Form();
var label = new Label(){Text = string.Format("{0:HH:mm:ss}", DateTime.UtcNow), AutoSize = true};
form.Controls.Add(label);
var taskController = new CancellationTokenSource();
var token = taskController.Token;
var task = Task.Run(() =>
{
for (var i=0; i<100; i++)
{
var text = string.Format("{0:HH:mm:ss}", DateTime.UtcNow);
Console.WriteLine(text); //lets us see what the task does after the form's closed
label.Text = text;
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation Token Detected");
break;
}
Thread.Sleep(1000);
}
}, token);
form.FormClosed += new FormClosedEventHandler(
(object sender, FormClosedEventArgs e) =>
{taskController.Cancel();}
);
form.Show();
}
var token = taskController.Token;
var task = Task.Run(() =>
{
//...
, token
}
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation Token Detected");
break;
}
Cancel
方法。在上面的代码中,我将其放在表单的FormClosed事件处理程序的逻辑下:
taskController.Cancel();
if
语句时才起作用,这意味着我们必须等待1秒,以使取消生效,这不是很好;如果延迟时间更长(例如5分钟),可能会非常痛苦。这里概述了一种解决方案:
i、 e.更换
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation Token Detected");
break;
}
Thread.Sleep(1000);
与
有关
WaitOne
方法的文档,请参阅。您需要先取消任务执行。阅读有关任务取消的详细信息。您不需要。先取消它。这就是为什么任务接受CancellationToken
s(并且显式地处理任务很少是必要的或有用的)。真的很有帮助!伟大的我真的很感激!您可以使用wait Task.Delay(1000,令牌),而不是WaitHandle代码>
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation Token Detected");
break;
}
Thread.Sleep(1000);
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation Token Detected");
break;
}
token.WaitHandle.WaitOne(1000);