Reputation: 8363
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;
}
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.
Added full code:
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");
});
}
}
So the qestion is how to catche ex. without asyn keyword???
Upvotes: 1
Views: 448
Reputation: 457207
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());
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.
Upvotes: 1
Reputation: 10708
When using async
/await
, exceptions are automatically unwrapped at the site of the await
. When using a Task
and .Wait()
, any exception are wrapped when they come out of the Task
, and thus getting information requires you to dig into the Task.Exception
property, since they do not propagate up the call stack.
See https://dotnetfiddle.net/MmEXsT
Upvotes: 0