【问题标题】:await operator can only be used within an async method - but method is asynchronawait 运算符只能在异步方法中使用 - 但方法是异步的
【发布时间】:2015-03-11 10:25:17
【问题描述】:

我想在 VS12 中使用 MessageDialog。到现在我都用过:

MessageDialog msgdlg = new MessageDialog("Choose a color", "How To Async #1");
msgdlg.DefaultCommandIndex = 1;
msgdlg.Commands.Add(new UICommand("Red", null, Colors.Red));
msgdlg.Commands.Add(new UICommand("Green", null, Colors.Green));
msgdlg.Commands.Add(new UICommand("Blue", null, Colors.Blue));

IAsyncOperation<IUICommand> asyncOp = msgdlg.ShowAsync();
asyncOp.Completed = OnMessageDialogShowAsyncCompleted;

现在我想消除回调并使用带有等待的匿名方法。出于测试目的,我使用了:

MessageDialog msgdlg = new MessageDialog("Choose a color", "#3");
msgdlg.Commands.Add(new UICommand("Red", null, Colors.Red));
msgdlg.Commands.Add(new UICommand("Green", null, Colors.Green));
msgdlg.Commands.Add(new UICommand("Blue", null, Colors.Blue));

// Show the MessageDialog
IAsyncOperation<IUICommand> asyncOp = msgdlg.ShowAsync();
IUICommand command = await asyncOp;

问题是,await 会产生错误,即使 ShowAsync() 显然是异步的。 “'await' 运算符只能在异步方法中使用。考虑使用 'async' 修饰符标记此方法并将其返回类型更改为 'Task'。”

这里有什么问题?


好的,感谢你们的 cmets 我现在这样做了:

Loaded += async (sender, args) =>
        {
            #region Using await (from C# 5.0 on)
            MessageDialog msgdlg = new MessageDialog("Choose a color", "#3");
            msgdlg.Commands.Add(new UICommand("Red", null, Colors.Red));
            msgdlg.Commands.Add(new UICommand("Green", null, Colors.Green));
            msgdlg.Commands.Add(new UICommand("Blue", null, Colors.Blue));

            // Show the MessageDialog
            IAsyncOperation<IUICommand> asyncOp = msgdlg.ShowAsync();
            IUICommand command = await asyncOp;

            #endregion
        };

现在可以使用了 - 非常感谢!

【问题讨论】:

  • 请出示您的方法声明。大概它没有async 修饰符。为什么不呢?
  • 一旦你去异步,几乎你的整个调用堆栈也应该被标记为异步。一直异步。
  • “即使 ShowAsync() 显然是异步的” - 没关系。它在抱怨您当前正在编写的方法,而不是您正在调用的任何方法。
  • 但是使用上面源代码的方法是构造函数(页面)。

标签: c# asynchronous async-await


【解决方案1】:

但使用上面源代码的方法是构造函数(页面)。

你不能有异步构造函数。将异步工作移出构造函数。也许将其移动到类似Load 的事件中。我不知道您使用的是什么 GUI 框架,但它们总是有 Load 事件。

【讨论】:

  • 好的,谢谢。我将代码移动到匿名方法中进行加载。非常感谢!
【解决方案2】:

您应该将您的方法设为async。您不能在non-async 函数中使用await

【讨论】:

  • 但是使用上面源代码的方法是构造函数(页面)。
【解决方案3】:

调用这些代码的函数也应该是异步的。请参阅下面的此 MS 官方示例中的详细信息。注意 ForgotPassword 的返回是 async Task 而不是 ActionResult。

public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
        {
        // Don't reveal that the user does not exist or is not confirmed
        return View("ForgotPasswordConfirmation");
    }

    var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
    var callbackUrl = Url.Action("ResetPassword", "Account", 
    new { UserId = user.Id, code = code }, protocol: Request.Url.Scheme);
    await UserManager.SendEmailAsync(user.Id, "Reset Password", 
    "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");        
    return View("ForgotPasswordConfirmation");
}

// If we got this far, something failed, redisplay form
return View(model);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多