Reputation: 990
I am still in the process of getting a handle on asynchronous programming and a bit puzzled on how to modify the following:
base virtual method:
public virtual async Task OnSuspendingAsync(object s, SuspendingEventArgs e)
{
// do some housekeeping actions upon suspending in the base class
await Task.Yield();
}
overriding method:
public override Task OnSuspendingAsync(object s, SuspendingEventArgs e)
{
// do some housekeeping actions on exiting/suspending
return base.OnSuspendingAsync(s, e);
}
the question:
Now if I use an awaitable in the overridden method (almost unavoidable), I need to change public override Task
to public override async Task
by adding the async
keyword as illustrated with a real example below.
public override async Task OnSuspendingAsync(object s, SuspendingEventArgs e)
{
try
{
// tidy up app temporary folder on exit
await ApplicationData.Current.ClearAsync(ApplicationDataLocality.Temporary);
}
catch { }
return base.OnSuspendingAsync(s, e); // this is wrong with awaitable!
}
In this case what should be the return base.OnSuspendingAsync(s, e);
change to (and why) which Visual Studio is rightly flagging as an error?
Upvotes: 1
Views: 1730
Reputation: 70652
You should await
the result:
public override async Task OnSuspendingAsync(object s, SuspendingEventArgs e)
{
try
{
// tidy up app temporary folder on exit
await ApplicationData.Current.ClearAsync(ApplicationDataLocality.Temporary);
}
catch { }
await base.OnSuspendingAsync(s, e);
}
Before you had await
in the method, it was fine for the method to run synchronously. You could do your synchronous logic, and then call the asynchronous base method and just pass the returned Task
object it uses to track its progress as your own return value.
But once you introduce await
into your method, now your own method is asynchronous. It will return at the very first await
, and the Task
returned to the caller represents the entire sequence of work your method will perform.
You want to make sure that Task
is not indicating a completion until the base method's Task
itself has indicated a completion. So the last thing you need to do in your now-asynchronous method is await
the result of the base method. In doing so, your method effectively doesn't terminate until after that happens, and thus its own Task
object (representing its own work) will not indicate completion until the base method's does.
Note that this is not the only possible way to address your scenario. But IMHO it is the most readable and simple to implement.
ADDENDUM:
I thought the above was sufficient to explain why await
is used, but perhaps not. To elaborate on the above, and in particular to answer the question "why is return
replaced by await
?":
return
statement isn't literally being replaced. In some contexts, return await
is correct. I.e. when the async
method does in fact return a value and that value is produced by some awaitable operation.return
statement go? Well: when you create an async
method, the return type changes. Instead of being the actual value returned by the method with a return
statement, the method's return type must be void
, Task
, or Task<T>
(where T
is of course some actual type or a defined type parameter).Task
because that's the method signature we have to comply with. But note that we use Task
when no actual value is returned (i.e. the method would otherwise be void
). So our async
method must not return anything. You can write return;
, but not return <some value>;
. I opted to omit the return entirely, but if you prefer having it, you can add return
; after the second await...
await
added. I hope this is more clear, per my explanation above. It's what causes the execution of the method to be temporarily suspended while the base.OnSuspendingAsync()
method is doing it's work (asynchronously). It works with async
to indicate to the compiler a point in the method when it can return, and then where execution will resume next.await
is what ensures the Task
returned by your OnSuspendingAsync()
override does not indicate completion until the base implementation has itself completed.Upvotes: 6