Sometimes the event pattern is used to raise events in MVVM applications by or a child viewmodel to send a message to its parent viewmodel in a loosely coupled way like this.
Parent ViewModel
searchWidgetViewModel.SearchRequest += (s,e) =>
{
SearchOrders(searchWidgitViewModel.SearchCriteria);
};
SearchWidget ViewModel
public event EventHandler SearchRequest;
SearchCommand = new RelayCommand(() => {
IsSearching = true;
if (SearchRequest != null)
{
SearchRequest(this, EventArgs.Empty);
}
IsSearching = false;
});
In refactoring my application for .NET4.5 I am making as much as code possible to use async
and await
. However the following doesn't work (well I really wasn't expecting it to)
await SearchRequest(this, EventArgs.Empty);
The framework definitely does this to call event handlers such as this, but I'm not sure how it does it?
private async void button1_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = "Click Started";
await DoWork();
textBlock2.Text = "Click Finished";
}
Anything I've found on the subject of raising events asynchrously is ancient but I can't find something in the framework to support this.
How can I await
the calling of an event but remain on the UI thread.
Edit: This doesn't work well for multiple subscribers, so unless you only have one I wouldn't recommend using this.
Feels slightly hacky - but I have never found anything better:
Declare a delegate. This is identical to EventHandler
but returns a task instead of void
public delegate Task AsyncEventHandler(object sender, EventArgs e);
You can then run the following and as long as the handler declared in the parent uses async
and await
properly then this will run asynchronously:
if (SearchRequest != null)
{
Debug.WriteLine("Starting...");
await SearchRequest(this, EventArgs.Empty);
Debug.WriteLine("Completed");
}
Sample handler :
// declare handler for search request
myViewModel.SearchRequest += async (s, e) =>
{
await SearchOrders();
};
Note: I've never tested this with multiple subscribers and not sure how this will work - so if you need multiple subscribers then make sure to test it carefully.