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

时间:2012-09-17 19:40:38

标签: c# asynchronous lambda 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!"));
}

不幸的是,!await post()不起作用,因为“类型'无效'是不可行的。”所以问题是,如何在此方法中定义我的参数以支持 awaitable 参数?

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

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

2 个答案:

答案 0 :(得分:35)

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

答案 1 :(得分:13)

您需要将其作为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>(不需要async / await,因为Post已经返回Task<bool>),并且更新方法为运行lambda。

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