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???
When using
async
/await
, exceptions are automatically unwrapped at the site of theawait
. When using aTask
and.Wait()
, any exception are wrapped when they come out of theTask
, and thus getting information requires you to dig into theTask.Exception
property, since they do not propagate up the call stack.See https://dotnetfiddle.net/MmEXsT
Methods that return
Task
- such asTask.Run
orasync
methods - will place any exceptions on that returnedTask
. It's up to you to observe that exception somehow. Normally this is done withawait
, like this:In your case, the problem is in this line:
In this code,
RunSomeTask
is returning aTask
, and thatTask
is never awaited. In order to observe the exception, you shouldawait
that task.