任务之外的异常处理 [英] Exception handling outside of Task
问题描述
刚刚注意到奇怪的事情:要从新任务的调用者中捕获异常,必须将 lambda 标记为异步!?即使委托根本没有等待操作符,它真的有必要吗?
Just noticed strange thing: to catch exception in caller from new Task, lambda MUST be marked as async!? Is it really necessary even if delegate has no await operators at all?
try
{
//Task.Run(() => // exception is not caught!
Task.Run(async () => // unnecessary async!?!
{
throw new Exception("Exception in Task");
}).Wait();
}
catch (Exception ex)
{
res = ex.Message;
}
为什么需要异步操作符?我能找到的所有文档都表明委托不能返回 Void,并且必须等待 Task 以将异常传播给调用者.
Why there is neccesary for async operator? All documentation i can find tells that delegate must not return Void and Task must be awaited for exception to propogate up to caller.
添加完整代码:
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.Run();
}
public void Run()
{
string result;
try
{
result = OnSomeEvent((s, ea) => RunSomeTask());
}
catch (Exception ex) // Try to catch unhandled exceptions here!
{
result = ex.Message;
}
Console.WriteLine(result);
Console.ReadKey();
}
// Some other Framework bult-in event (can not change signature)
public string OnSomeEvent(EventHandler e)
{
e.Invoke(null, new EventArgs());
return "OK";
}
private async Task RunSomeTask()
{
await Task.Run(async () => // do not need async here!!!
//await Task.Run(() => // caller do not catches exceptions (but must)
{
throw new Exception("Exception in Task1");
});
}
}
所以问题是如何抓住前任.没有 asyn 关键字???
So the qestion is how to catche ex. without asyn keyword???
推荐答案
返回 Task
的方法 - 例如 Task.Run
或 async
方法 - 将在返回的 Task
上放置任何异常.以某种方式观察该异常取决于您.通常这是通过 await
完成的,就像这样:
Methods that return Task
- such as Task.Run
or async
methods - will place any exceptions on that returned Task
. It's up to you to observe that exception somehow. Normally this is done with await
, like this:
await Task.Run(() => { throw ... });
就您而言,问题出在这一行:
In your case, the problem is in this line:
result = OnSomeEvent((s, ea) => RunSomeTask());
在这段代码中,RunSomeTask
正在返回一个 Task
,并且从不等待 Task
.为了观察异常,你应该await
那个任务.
In this code, RunSomeTask
is returning a Task
, and that Task
is never awaited. In order to observe the exception, you should await
that task.
这篇关于任务之外的异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!