Reputation: 568
i have a method in a library that is free of any controls that is wrapped in a Task.Factory Syntax and i want to properly handle the exception it would throw and show the message in the UI. Consider below code:
Project.WinForms:
public void button1_Click(object sender, EventArgs e)
{
try
{
library1.RunTask();
}
catch(Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
Project.Core:
public void RunTask()
{
Task.Factory.StartNew(() => {
try
{
throw new Exception("SAMPLE_EXCEPTION");
}
catch(Exception)
{
throw;
}
});
}
What happening when running the compiled executable is that no Exception is Shown, the UI is stuck in a progressing-like state but in reality, an exception has happened in the other thread. However, when debugging the solution, an exception is thrown thereby breaking the execution of the code as below:
Upvotes: 1
Views: 138
Reputation: 141462
Your RunTask
method is asynchronous and is throwing an exception. The official documentation has a section on exceptions in async methods, which states:
To catch the exception, await the task in a try block, and catch the exception in the associated catch block.
So let's do that by making two changes:
Task
that you start in RunTask()
.await
that task in a try block in your event handler.Here is a simplified example of your scenario.
// Use the async keyword,
// so we can use await in the method body
public async void button1_Click(object sender, EventArgs e)
{
try
{
// await the completion of the task,
// without blocking the UI thread
await RunTask();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
// Change the signature to return a Task
public Task RunTask()
{
// Return the task that you started
return Task.Factory.StartNew(() =>
{
throw new Exception("SAMPLE_EXCEPTION");
});
}
// The following emulates your button click scenario
public event EventHandler<EventArgs> ButtonClickEvent;
public static void Main()
{
var p = new Program();
p.ButtonClickEvent += p.button1_Click;
p.ButtonClickEvent(p, new EventArgs());
}
For a fuller explanation of what's happening, I refer you to Async/Await - Best Practices in Asynchronous Programming.
There is one important item to note, though. We return async void
from the button1_Click
event handler, even though it is almost always better to return async Task
from an asynchronous method. Event handlers must return void, though, so we cannot use async Task
and must use async void
instead.
Upvotes: 5