38

先上代码。这就是我想要做的。我很接近,但我想我只需要修复我在 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!"));
}

不幸的是,这!await post()不起作用,因为“类型 'void' 是不可等待的。” 所以问题是,我如何在这个方法中定义我的参数来支持一个可等待的参数?

下面是 TwitterAction().Post() 的定义方式...

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

4

2 回答 2

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

- 编辑 -

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);
}
于 2012-09-17T19:45:06.670 回答
17

您需要将其作为 a 传递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!"));
}

如果您不想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!"));
}

这会导致 lambda 返回Task<bool>(no async/ awaitrequired,因为Post已经返回Task<bool>),并且 update 方法会运行 lambda。

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

于 2012-09-17T19:43:46.873 回答