C# 如何正确地取消任务并捕获OperationCanceledException?
这个问题已经被问过了,但我还是不明白。。。我试图取消一项任务,但当我包含ThrowIfCancellationRequested()时,它不会被捕获,如果我不包含它,GUI将冻结 下面是我的代码,它在没有ThrowIfCancellationRequested()的情况下运行,但冻结了GUI:C# 如何正确地取消任务并捕获OperationCanceledException?,c#,.net,task,C#,.net,Task,这个问题已经被问过了,但我还是不明白。。。我试图取消一项任务,但当我包含ThrowIfCancellationRequested()时,它不会被捕获,如果我不包含它,GUI将冻结 下面是我的代码,它在没有ThrowIfCancellationRequested()的情况下运行,但冻结了GUI: public void StartProcess(double myvariable) { tokenSource = new CancellationTokenSource()
public void StartProcess(double myvariable)
{
tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
processThread = Task.Factory.StartNew(() =>
{
while (true)
{
//Do some work with myvariable
if (token.IsCancellationRequested)
{
break;
}
}
}, token);
}
对于未捕获到ThrowIfCancellationRequested()的代码,调试器将在行标记上停止。ThrowIfCancellationRequested():
我做错了什么?通过取消请求的
是取消任务的正确方法。你需要了解的是,当你取消一项任务时,没有例外。只有任务的状态
将设置为已取消
。任务中的try-catch块将不起任何作用。
要获取异常,您需要在异步方法中等待任务,或者使用Wait方法等待任务完成。不建议使用Wait方法,因为在任务完成之前您将阻塞当前线程
下面是一个如何从代码中实现的建议
public static Task StartProcess(double myvariable)
{
tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
return Task.Factory.StartNew(() =>
{
while (true)
{
//Do some work with myvariable
token.ThrowIfCancellationRequested();
}
}, token);
}
public async Task ExecuteProcess(double myvariable)
{
try
{
await StartProcess(myvariable);
}
catch (OperationCanceledException ex)
{
Console.WriteLine("Process Thread Canceled");
}
catch (Exception ex)
{
Console.WriteLine("ERROR");
}
}
ExecuteProcess方法演示了如何调用函数以获取异常。这样,如果从UI线程调用该方法,也可以防止GUI阻塞
我建议您阅读,以进一步了解其工作原理。如果您通过取消安装请求调用,则根本不需要检查iscancellationrequest
。此外,您不需要中断
。如果请求取消,Throw…将抛出一个异常,并且无论如何都不会进入中断。如果未请求取消,则抛出…将不会抛出,且不需要进行If检查。您应使用标记替换完整的If块。ThrowIfCancellationRequested()代码>哪个做的相同。
public static Task StartProcess(double myvariable)
{
tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
return Task.Factory.StartNew(() =>
{
while (true)
{
//Do some work with myvariable
token.ThrowIfCancellationRequested();
}
}, token);
}
public async Task ExecuteProcess(double myvariable)
{
try
{
await StartProcess(myvariable);
}
catch (OperationCanceledException ex)
{
Console.WriteLine("Process Thread Canceled");
}
catch (Exception ex)
{
Console.WriteLine("ERROR");
}
}