From MSDN:
If the method that the async keyword modifies doesn't contain an await expression or statement, the method executes synchronously.
In VSPackage I have 2 commands:
private void FirstMenuCommand(object sender, EventArgs e)
{
ThrowElevationRequired();
}
private void SecondMenuCommand(object sender, EventArgs e)
{
ThrowElevationRequiredAsync();
}
Both of this commands force authorization elevation:
private void ThrowElevationRequired()
{
Marshal.ThrowExceptionForHR(unchecked((int)0x800702E4));
}
private async void ThrowElevationRequiredAsync()
{
Marshal.ThrowExceptionForHR(unchecked((int)0x800702E4));
}
The async
prefix is the only difference for these methods above (no await
inside, just exception with specific failure HRESULT thrown). Now, I know the asynchronous version has no sense to be here but I'd like to show an issue related with that. Namely, while the first command invoke results in this popup:
the second command seems to do nothing. What is the reason? (Resharper shows the async
keyword as redundant, which is theoretically true, but as it is shown above, behavior can be very different).
the second command seems to do nothing. What is the reason?
The second method is asynchronous, which means exceptions are never thrown directly to the caller - whether the exception occurs while the method is executing synchronously or not. An async method which returns a Task
will make the task "faulted" if the method throws an exception... but when the async method is void
(which should almost never be the case) it call AsyncVoidMethodBuilder.SetException
- the behaviour of which will depend on the synchronization context.
The async
modifier is definitely not redundant in that it does affect behaviour, as you've noted - and that's the correct behaviour, working as designed... it's just that when an async void
method throws an exception, there's the natural question of what should catch it.
User contributions licensed under CC BY-SA 3.0