I have Async method which is called inside button_click. Async method runs 3 different void's and each void has It's own error handling. If any error inside those 3 methods occure I want to show that particular error message and stop code inside button_click - which also runs more non-async method and has It's error handling. What I did was this (example):
private void button1_Click(object sender, EventArgs e)
{
try
{
//calling non-async method, if It fails It should show error
//inside this event
Method1();
if (TestAsync().IsCanceled)
{
return;
}
MessageBox.Show("Test");
}
catch (Exception)
{
MessageBox.Show("Async method failed and this message should not be diplayed!");
throw;
}
}
public async Task<bool> TestAsync()
{
bool completed = await Task.Run(() => MethodToComplete());
return completed;
}
private bool MethodToComplete()
{
try
{
//renaming file, but intentionally fail for test purpose
Directory.Move("fail_this_method", "fail");
return true;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
return true;
throw;
}
}
The result of this example is - It does display error message from void which is called asynchronously and doesn't show error message from button_click. But It also displays MessageBox.Show("Test"); which shouldn't, code in button_click should stop immidiately if Async fails.
I hope I was clear enough, any help kindly appreaciated !
Before async-await there were other task handling methods, like Task.ContinueWith
, Task.IsCanceled
etc.
If you plan to use async-await, don't mix them with these older functions.
When you decide to use async-await, stick to the following rules:
Task<TResult>
instead of TResult
and Task
instead of void
Furthermore:
InvokeRequired
, locks and mutexes ConfigureAwait(false)
after the await. This will speed up the process, with the disadvantage that the continuing thread does not have the user interface context. Therefore you can't access windows Form
controls. Keeping this in mind, you code could be as follows:
private async void button1_Click(object sender, EventArgs e)
{
// this function must be async because if awaits
// it is an event hander, hence it returns void instead of Task
try
{
Method1();
// call TestAsync, if you do not need the result right now,
// do not await yet
var myTask = TestAsync();
// as soon as TestAsync has to await, it continues here:
// results from TestAsync are not available yet
DoSomeOtherProcessing();
// now you need the result from testAsync; await the Task
bool result = await myTask;
ProcessResult(result);
}
catch (Exception)
{
...
}
}
A Task
that is cancelled, should throw TaskCanceledException
. You should not check MyTask.IsCanceled
, but catch this exception.
Articles that helped me understanding async-await
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.