Async and Visual Studio failure handling

1

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:

enter image description here

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).

.net
visual-studio
async-await
visual-studio-extensions
vspackage
asked on Stack Overflow Apr 15, 2014 by jwaliszko

1 Answer

4

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.

answered on Stack Overflow Apr 15, 2014 by Jon Skeet

User contributions licensed under CC BY-SA 3.0