Created
August 30, 2012 20:40
-
-
Save clemensv/3540372 to your computer and use it in GitHub Desktop.
Yes, a goto courtesy of async/await's scoping issues with "catch".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The scoping model in "catch" doesn't allow for async/await handling because | |
// catch needs to be able to rethrow without messaging up the stack frame, i.e. "throw;" | |
// There's obviously an alternate non-goto solution here with a result variable and a | |
// subsequent switch on that result, but if you code that up, the switch looks like | |
// a longer, uglier variant of the gotos. | |
static async Task LoopedReceive(Func<Task<BrokeredMessage>> receiveCallbackAsync, | |
Func<BrokeredMessage, Task<bool>> messageReceivedCallbackAsync, | |
CancellationToken token) | |
{ | |
bool continueLoop = true; | |
while(continueLoop && (!token.CanBeCanceled || !token.IsCancellationRequested)) | |
{ | |
try | |
{ | |
var message = await receiveCallbackAsync(); | |
if (message != null) | |
{ | |
try | |
{ | |
continueLoop = await messageReceivedCallbackAsync(message); | |
} | |
catch (Exception e) | |
{ | |
Trace.TraceError(CallbackThrewExceptionExceptionText, e); | |
goto Abandon; | |
} | |
continue; | |
Abandon: | |
AbandonMessage(message); | |
continue; | |
} | |
} | |
catch (MessagingException me) | |
{ | |
if (!me.IsTransient) | |
{ | |
throw; | |
} | |
} | |
} | |
} | |
static async void AbandonMessage(BrokeredMessage message) | |
{ | |
try | |
{ | |
await message.AbandonAsync(); | |
} | |
catch (Exception e) | |
{ | |
if (e.IsFatal()) | |
{ | |
throw; | |
} | |
Trace.TraceError(UnableToAbandonMessageExceptionText, e); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment