Reputation: 710
Does try catch outside of: await Task.Run(() =>
make sense or just use them only inside of await?
private async void Test()
{
try
{
await Task.Run(() =>
{
try
{
DoingSomething();
}
catch (Exception ex)
{
log.Error(ex.Message);
}
});
}
catch (Exception ex)
{
log.Error(ex.Message);
}
}
Upvotes: 18
Views: 25223
Reputation: 301
This is the behavior in .Net 6:
try{
await Task.Run(()=> & call whatever method );
}
catch { handle the exception } <-- the catch will never get hit. An unhandled exception in the Task.Run line will happen
However, this will work:
try{
await Task.Run(async ()=> & call some method );
}
catch(Exception ex){
handle the exception
}
The async before the ()=> has to be there for .Net 6
I've just confirmed this.
Upvotes: -1
Reputation: 7602
If you handle Exception
inside the delegate (in your case just for logging purpose), await
will not raise an exception in normal circumstances. This should be fine.
private async Task Test()
{
await Task.Run(() =>
{
try
{
DoingSomething();
}
catch (Exception ex)
{
log.Error(ex.Message);
}
});
}
However, since you are await
ing the Task
, most probably, there will be some DoSomethingElse
in the Test
method, which might be affected by the outcome of the Task
- in which case it also makes sense to have a try/catch
around await
.
private async Task Test()
{
try
{
await Task.Run(() =>
{
try
{
DoingSomething();
}
catch (SomeSpecialException spex)
{
// it is OK to have this exception
log.Error(ex.Message);
}
});
DoSomethingElse(); // does not run when unexpected exception occurs.
}
catch (Exception ex)
{
// Here we are also running on captured SynchronizationContext
// So, can update UI to show error ....
}
}
Upvotes: 14
Reputation: 2577
You can add try catch to outside code too. The compiler will execute catch section when an exception happens during the async call. Here is more details why would you need try catch around await http://msdn.microsoft.com/en-us/library/vstudio/0yd65esw.aspx look Exceptions in Async Methods
Upvotes: 2
Reputation: 456417
If the delegate you pass to Task.Run
raises an exception, then you can catch it outside the Task.Run
when you await
the returned task.
You shouldn't think of await
as though it was a block. There's no such thing as "inside of await". Instead, think of await
as an operator that takes a single argument (in this case, the Task
returned by Task.Run
). Task.Run
will catch exceptions from its delegate and place them on the returned Task
; await
will then propagate that exception.
Upvotes: 14