将同步代码转换为异步代码未处理 System.OperationCanceledException:'The operation was canceled.'
Converting sync to async code got unhandled System.OperationCanceledException: 'The operation was canceled.'
我正在尝试将我的同步功能转换为异步功能。在我所有的同步函数中,我都有一个用于函数、任务和并行块的取消标记。在调用异步函数之前我有一个 try/catch 块,但我遇到了一个未处理的异常:
Exception thrown: 'System.OperationCanceledException' in
System.Threading.Tasks.Parallel.dll An exception of type
'System.OperationCanceledException' occurred in
System.Threading.Tasks.Parallel.dll but was not handled in user code
The operation was canceled.
我的异步函数:
public async Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) =>
await Task.Run(() => Decode(fileFullPath, fileDecodeType, progress), progress?.Token ?? default);
我怎么称呼它:
try
{
await SlicerFile.DecodeAsync(fileName, fileDecodeType, Progress);
}
catch (OperationCanceledException) { } // Do not work!
catch (Exception exception) // Works for other exceptions
{
await this.MessageBoxError(exception.ToString(), "Error opening the file");
}
catch (OperationCanceledException)
不会在取消事件中达到,也不会达到 catch (Exception exception)
。由于我的尝试是最重要的,为什么它没有捕获到异常?
但如果我这样做:
public async Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) =>
await Task.Run(() => throw new Exception("Test"));
我得到了通用异常的异常捕获(已处理)
另一方面,旧代码可以正常工作并处理 OperationCanceledException
:
var task = await Task.Factory.StartNew( () =>
{
try
{
SlicerFile.Decode(fileName, fileDecodeType, Progress);
return true;
}
catch (OperationCanceledException) {} // Works!
catch (Exception exception)
{
Dispatcher.UIThread.InvokeAsync(async () =>
await this.MessageBoxError(exception.ToString(), "Error opening the file"));
}
return false;
});
我做错了什么?
Task.Run 的结果不一定需要在那里等待。您可以只 return 运行 任务,然后该方法不再需要等待或异步。
Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) => Task.Run(() =>
Decode(fileFullPath, fileDecodeType, progress), progress?.Token ?? default);
并且由于您正在传递一个令牌,您可以监视它以干净地退出解码方法,而不是试图捕获并忽略操作取消的异常。
如果可以的话,将解码方法本身设为异步会更好。它已经 return 是一个任务,所以它可以 return 一个任务(或其他)。您的旧代码也以同样的方式异步,因此我可以看到您的新代码没有任何优势。
我正在尝试将我的同步功能转换为异步功能。在我所有的同步函数中,我都有一个用于函数、任务和并行块的取消标记。在调用异步函数之前我有一个 try/catch 块,但我遇到了一个未处理的异常:
Exception thrown: 'System.OperationCanceledException' in System.Threading.Tasks.Parallel.dll An exception of type 'System.OperationCanceledException' occurred in System.Threading.Tasks.Parallel.dll but was not handled in user code The operation was canceled.
我的异步函数:
public async Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) =>
await Task.Run(() => Decode(fileFullPath, fileDecodeType, progress), progress?.Token ?? default);
我怎么称呼它:
try
{
await SlicerFile.DecodeAsync(fileName, fileDecodeType, Progress);
}
catch (OperationCanceledException) { } // Do not work!
catch (Exception exception) // Works for other exceptions
{
await this.MessageBoxError(exception.ToString(), "Error opening the file");
}
catch (OperationCanceledException)
不会在取消事件中达到,也不会达到 catch (Exception exception)
。由于我的尝试是最重要的,为什么它没有捕获到异常?
但如果我这样做:
public async Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) =>
await Task.Run(() => throw new Exception("Test"));
我得到了通用异常的异常捕获(已处理)
另一方面,旧代码可以正常工作并处理 OperationCanceledException
:
var task = await Task.Factory.StartNew( () =>
{
try
{
SlicerFile.Decode(fileName, fileDecodeType, Progress);
return true;
}
catch (OperationCanceledException) {} // Works!
catch (Exception exception)
{
Dispatcher.UIThread.InvokeAsync(async () =>
await this.MessageBoxError(exception.ToString(), "Error opening the file"));
}
return false;
});
我做错了什么?
Task.Run 的结果不一定需要在那里等待。您可以只 return 运行 任务,然后该方法不再需要等待或异步。
Task DecodeAsync(string? fileFullPath, FileDecodeType fileDecodeType, OperationProgress? progress = null) => Task.Run(() =>
Decode(fileFullPath, fileDecodeType, progress), progress?.Token ?? default);
并且由于您正在传递一个令牌,您可以监视它以干净地退出解码方法,而不是试图捕获并忽略操作取消的异常。
如果可以的话,将解码方法本身设为异步会更好。它已经 return 是一个任务,所以它可以 return 一个任务(或其他)。您的旧代码也以同样的方式异步,因此我可以看到您的新代码没有任何优势。