Free mag vol1 | Page 803

CHAPTER 19  MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING private async void btnCallMethod_Click(object sender, EventArgs e) { this.Text = await DoWorkAsync(); } private async Task DoWorkAsync() { return await Task.Run(() => { Thread.Sleep(10000); return "Done with work!"; }); } } Async Methods Returning Void Currently, our DoWork() method is returning a Task, which contains “real data” for the caller that will be obtained transparently via the await keyword. However, what if you want to build an asynchronous method that returns void? In this case, we make use of the nongeneric Task class and omit any return statement, like so: private async Task MethodReturningVoidAsync() { await Task.Run(() => { /* Do some work here... */ Thread.Sleep(4000); }); } The caller of this method, such as a second button Click event handler, would then use the await and async keywords as so: private async void btnVoidMethodCall_Click(object sender, EventArgs e) { await MethodReturningVoidAsync(); MessageBox.Show("Done!"); } Async Methods with Multiple Awaits It is completely permissible for a single async method to have multiple await contexts within its implementation. Assume our application now has a third button Click event handler that has been marked with the async keyword. In the previous parts of this example, the Click handlers purposely called some external method that runs the underlying Task; however, you could inline this logic via a set of lambda expressions as so: private async void btnMutliAwaits_Click(object sender, EventArgs e) { await Task.Run(() => { Thread.Sleep(2000); }); MessageBox.Show("Done with first task!"); 748