我有一个奇怪的问题,结合 async/await 使其工作: 我创建了一个小程序,它应该基本上处理每个操作的 try/catch:
internal static void HandledAction(Action action, Info infoBar)
{
try
{
action();
}
catch (Exception ex)
{
infoBar.SetError("An Exception occured: " + ex.Message);
WriteLog(ex.StackTrace);
}
没什么特别的,但它是值得的,因为更改错误处理非常容易。 但是,如果我想在 Lambda 中实现数据异步,会发生什么?让我们举个简单的例子:
private void mnuImportData_Click(object sender, RoutedEventArgs e)
{
ActionHelper.HandledAction(async () =>
{
throw new NotImplementedException("Ups");
}, infoMain);
}
当然,HandledAction 被调用,通过,因为它取回了指针,并且抛出了异常,当然没有被处理。
我想我必须创建一个 AsyncHandledAction,并将操作设置为异步,但是有没有更简单的方法来解决这个问题?
我想很多人都使用中央异常处理,对此有更好的解决方案吗?
提前致谢
马蒂亚斯
编辑:我创建了一个示例,它应该显示我需要的 netter:我基本上不希望我传递的整个 Action 是可等待的,但是 Lambda 中的一个调用是:
ActionHelper.HandledActionAsync(() =>
{
//elided
CheckFileResult rslt = await excelImport.CheckFilesAsync(tmpPath);
//elided
}, infoMain);
当然,通过这样做,我得到了错误:
错误 3 'await' 运算符只能在异步 lambda 表达式中使用。考虑使用“async”修饰符标记此 lambda 表达式。
最佳答案
原因是:Action而不是Func。由于你的:
async () =>
{
throw new NotImplementedException("Ups");
}
事实上是:
async void Method() { }
当Func<Task>
是:
async Task Method() { }
Async void 将捕获 SynchronizationContext.Current
当抛出异常时,它将被发布到 SynchronizationContext
通过 SynchronizationContext.Post()
-(在 Windows 运行时中,您可以捕获这些类型的异常)。如果是ASP.NET/Console application
SynchronizationContext.Current
返回 null,这意味着异常将传播到线程池,我不确定,但我认为不可能捕获它。但是当返回时 Task
通过异步方法异常可以通过这个返回的任务编码给调用者。还值得一提的是,异步 lambda 表达式总是更喜欢带有 Func<Task>
的方法。在 Action
.一般规则是:永远不要使用 async void
( async Action
) 除非它是“顶级方法”(在示例事件处理程序中)。
关于c# - 异步/等待 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25647062/