await运算符只能在异步方法中使用 - 但方法是异步的

时间:2014-01-24 11:18:16

标签: c# asynchronous async-await

我想在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;

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

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;

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

这里的问题是什么?


好的,感谢您的评论,我现在这样做了:

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

现在它有效 - 非常感谢!

3 个答案:

答案 0 :(得分:4)

  

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

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

答案 1 :(得分:2)

您应该制作方法async。您不能在await函数中使用non-async

答案 2 :(得分:0)

调用这些代码的函数也应该是异步的。请参阅此MS官方样本的详细信息。注意ForgotPassword的返回是异步任务&lt; ActionResult&gt;而不是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);
}