I wanna launch the LoadDataAsync
in 2 ways. First by an event with the subcription in FormLoad()
and by a classic method ManualLoad()
.
But I can't make it work.
I can't make subscription on task return. With void
it's works, but with void
can't await
in the ManualLoad()
method. How make both ways work?
public delegate void ProductDelegate(long? iShopProductId);
public event ProductDelegate ProductSelectionChanged = delegate { };
public async Task LoadDataAsync(long? iProductId)
{
//await action....
}
//first way
public void FormLoad()
{
this.ProductSelectionChanged += LoadDataAsync //UNDERLINED ERROR;
}
//second way
public async Task ManualLoad()
{
await LoadDataAsync(2);
}
Since delegates (and events are delegates) implement the Asynchronous Programming Model (APM), you could use the TaskFactory. FromAsync method.
The solution is extremely simple: just mark the event handler as async. You should never use async void methods, instead use async Task or async Task<T1,...>. The exception, apparently, is event handlers. And it kind of makes sense: an event handler is designed to be called asynchronously.
If you need to access an event in an asynchronous way, then you should call event. persist() at the beginning of the function.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
As events do not support async Task
you neeed to work around that via "wrapping" it, e.g.:
this.ProductSelectionChanged += async (s, e) => await LoadDataAsync();
Here I created an anonymous method/handler with a signature of async void
which does nothing else then await
the task-returning LoadDataAsync
-method (may you should add ConfigureAwait(false)
, depending on your specific use case).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With