【发布时间】:2015-07-03 03:35:02
【问题描述】:
刚刚注意到奇怪的事情:要在新任务的调用者中捕获异常,必须将 lambda 标记为异步!?即使 delegate 根本没有 await 操作符,真的有必要吗?
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;
}
为什么需要异步操作符? 我能找到的所有文档都告诉我,delegate 不能返回 Void 并且 Task 必须等待异常传播给调用者。
添加完整代码:
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");
});
}
}
所以问题是如何抓住前任。没有异步关键字???
【问题讨论】:
-
您不需要使用
async- 我怀疑抛出异常会破坏委托类型推断。尝试明确指定委托类型。 -
你说异常没有被捕获!当不使用异步时。但确实被抓住了。这是您的实际代码吗?
-
@Lee 是正确的。我记得几个月前读过关于这个确切主题的副本。抛出异常会改变匿名委托的返回类型。
-
@SriramSakthivel,更新了实际代码。
-
这两种情况会发生什么?你说的作品是什么意思?你能说出你在这两种情况下观察到的行为,而不是说有效吗?