异步方法中的异步方法

本文关键字:异步方法 | 更新日期: 2023-09-27 18:17:33

我的问题:在继续之前如何等待异步方法的输入?

一些背景信息:我有一个c#应用程序扫描QR码,然后根据扫描的值加载数据。上面的工作,但现在我想让应用程序询问扫描的值是否是正确的卡片。

应用的代码如下:

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;
    }
}

问题是,Continue在第1块代码中调用if (Continue)时仍然为假,因为消息框是异步的,并且应用程序在消息框完成之前继续执行if语句。

我已经尝试给HandleScanResult()一个任务返回类型并调用await HandleScanResult(t.Result);。这应该使应用程序在继续执行if语句之前等待HandleScanResult()。但是,这会返回以下错误:

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

因此我的问题是如何在继续之前等待输入

异步方法中的异步方法

您不能等到async void方法完成。Task是返回类型,它允许调用者获得某种指示操作已完成的信号。您做了正确的事情,将该方法更改为async Task

对于错误消息,它告诉您可以通过以下方式消除编译器错误:

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

注意t前面多了一个async

然而,仅仅因为这可以编译,并不意味着这就是你应该做的。你把事情弄得太复杂了,在这里根本不需要使用ContinueWith。当你在async方法体中,你已经使用的await操作符可以做ContinueWith会做的事情,但是以更直接的方式。

var scanResult = await scanner.Scan();
if (scanResult != null)
    await HandleScanResult(scanResult);