传递*Awaitable*匿名函数作为参数

jed*_*mao 31 c# lambda asynchronous parameter-passing

代码优先.这就是我想要做的.我很接近,但我想我只需要修改我在UpdateButton方法中定义参数的方式.

private async void UpdateButton(Action<bool> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}

private void PostToTwitter()
{
    UpdateButton(async () => await new TwitterAction().Post("Hello, world!"));
}

private void PostToFacebook()
{
    UpdateButton(async () => await new FacebookAction().Post("Hello, world!"));
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这!await post()不起作用,因为"Type'void'不是等待的." 所以问题是,如何在此方法中定义我的参数以支持等待参数?

这是TwitterAction().Post()的定义方式......

public virtual async Task<bool> Post(string messageId){...}

L.B*_*L.B 37

private async void UpdateButton(Func<Task<bool>> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

UpdateButton(()=>Post("ss"));

private async void UpdateButton(Func<Task<bool>> post)
{
    if (!await post())
        this.Text = "Error posting message.";
}

public virtual async Task<bool> Post(string messageId)
{
    return await Task.Factory.StartNew(() => true);
}
Run Code Online (Sandbox Code Playgroud)

  • 啊,那当然是我的错误。当我尝试@Reed的示例时,我忘记将`()`放回原处。好答案!谢谢。 (2认同)

Ree*_*sey 14

你需要把它作为一个Task<bool>而不是一个Action<bool>.

这提供了"等待"的东西.

鉴于您当前的代码,我相信这会有效:

private async Task UpdateButtonAsync(Task<bool> post)
{
    if (!await post)
        ErrorBox.Text = "Error posting message.";
}

// This will work if Post returns Task<bool> in the current API...
private void PostToTwitter()
{
    UpdateButtonAsync(new TwitterAction().Post("Hello, world!"));
}
Run Code Online (Sandbox Code Playgroud)

如果您不想Task<bool>立即启动,并且需要将其保持为传递lambda,则仍然没有理由使lambda异步.在这种情况下,您可以使用:

private async Task UpdateButtonAsync(Func<Task<bool>> post)
{
    if (!await post())
        ErrorBox.Text = "Error posting message.";
}

// This will work if Post returns Task<bool> in the current API...
private void PostToTwitter()
{
    UpdateButtonAsync(() => new TwitterAction().Post("Hello, world!"));
}
Run Code Online (Sandbox Code Playgroud)

这会导致lambda返回Task<bool>(no async/ awaitrequired,Post已经返回Task<bool>),以及update方法来运行lambda.

就个人而言,我发现第一个选项(上面)更简单,并怀疑它更可能是你想要的.鉴于您的API已经返回Task<T>,您可以直接传递await它.