The normal behavior for exceptions thrown from async Task
methods is to stay dormant until they get observed later, or until the task gets garbage-collected.
I can think of cases where I may want to throw immediately. Here is an example:
public static async Task TestExAsync(string filename)
{
// the file is missing, but it may be there again
// when the exception gets observed 5 seconds later,
// hard to debug
if (!System.IO.File.Exists(filename))
throw new System.IO.FileNotFoundException(filename);
await Task.Delay(1000);
}
public static void Main()
{
var task = TestExAsync("filename");
try
{
Thread.Sleep(5000); // do other work
task.Wait(); // wait and observe
}
catch (AggregateException ex)
{
Console.WriteLine(new { ex.InnerException.Message, task.IsCanceled });
}
Console.ReadLine();
}
I could use async void
to get around this, which throws immediately:
// disable the "use await" warning
#pragma warning disable 1998
public static async void ThrowNow(Exception ex)
{
throw ex;
}
#pragma warning restore 1998
public static async Task TestExAsync(string filename)
{
if (!System.IO.File.Exists(filename))
ThrowNow(new System.IO.FileNotFoundException(filename));
await Task.Delay(1000);
}
Now I can handle this exception right on the spot with Dispatcher.UnhandledException
or AppDomain.CurrentDomain.UnhandledException
, at least to bring it to the user attention immediately.
Is there any other options for this scenario? Is it perhaps a contrived problem?