0

My question: How do I wait for the input from an async method before going on?

Some background info: I have a C# app which scans for a QR code, and then loads data on basis of the value scanned. The above works, but now I want the app to ask whether the value scanned is the right card.

The applied code is as follows:

using ZXing.Mobile;
MobileBarcodeScanner scanner;
private bool Correct = false;
//Create a new instance of our scanner
scanner = new MobileBarcodeScanner(this.Dispatcher);
scanner.Dispatcher = this.Dispatcher;
await scanner.Scan().ContinueWith(t =>
{
    if (t.Result != null)
        HandleScanResult(t.Result);
});

if (Continue)
{
    Continue = false;
    Frame.Navigate(typeof(CharacterView));
}

HandleScanResult(Result) being (skimmed down):

async void HandleScanResult(ZXing.Result result)
{
    int idScan = -1;
    if (int.TryParse(result.Text, out idScan) && idScan != -1)
    {
        string ConfirmText = CardData.Names[idScan] + " was found, is this the card you wanted?";
        MessageDialog ConfirmMessage = new MessageDialog(ConfirmText);
        ConfirmMessage.Commands.Add(new UICommand("Yes") { Id = 0 });
        ConfirmMessage.Commands.Add(new UICommand("No") { Id = 1 });

        IUICommand action = await ConfirmMessage.ShowAsync();

        if ((int) action.Id == 0)
            Continue = true;
        else
            Continue = false;
    }
}

The problem is, Continue remains false the the moment if (Continue) is called in the 1st block of code, due to the message box being asynchronous and the app continuing to the if-statement before the message box is done.

I have already tried giving HandleScanResult() a Task return type and calling await HandleScanResult(t.Result);. This should make the app wait for HandleScanResult() before going on to the if-statement. However, this returns the following error:

The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.

Hence my question on how to wait for the input before going on.

0

1 Answer 1

2

You cannot wait until an async void method has finished. Task is the return type that allows callers to get some sort of signal indicating the operation has completed. You did the right thing changing that method to async Task.

As for the error message, it's telling you that you can get rid of the compiler error as follows:

await scanner.Scan().ContinueWith(async t =>
{
    if (t.Result != null)
        await HandleScanResult(t.Result);
});

Note the extra async before t.

However, just because this compiles, doesn't mean this is what you should be doing. You're making things overly complicated, and you don't need to use ContinueWith at all here. When you're in an async method body, the await operator that you're already using can do what ContinueWith would've done, but in a more straightforward manner.

var scanResult = await scanner.Scan();
if (scanResult != null)
    await HandleScanResult(scanResult);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! I had the ContinueWith from some sample code, hence why I used it. Thank you again, I'd +1 if I had more rep ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.