C# 传递一个 *Awaitable* 匿名函数作为参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12466049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:21:31  来源:igfitidea点击:

Passing an *Awaitable* Anonymous Function as a Parameter

c#asynchronouslambdaparameter-passing

提问by jedmao

Code first. This is what I'm trying to do. I'm close, but I think I just need to fix the way I've defined my parameter in the UpdateButton method.

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

Unfortunately, the !await post()doesn't work because, "Type 'void' is not awaitable." So the question is, how do I define my parameter in this method to support an awaitableparameter?

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

Here's how the TwitterAction().Post() is defined...

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

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

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

采纳答案by L.B

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

--EDIT--

- 编辑 -

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

回答by Reed Copsey

You need to pass this as a Task<bool>, not an Action<bool>.

您需要将其作为 a 传递Task<bool>,而不是Action<bool>.

This provides something that's "awaitable".

这提供了“可等待”的东西。

I believe this will work, given your current code:

鉴于您当前的代码,我相信这会起作用:

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


If you do not want to start the Task<bool>immediately, and need to keep it as passing a lambda, there is still no reason for the lambda to be async. In that case, you could use:

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

This causes the lambda to return the Task<bool>(no async/awaitrequired, as Postalready returns Task<bool>), and the update method to run the lambda.

这会导致 lambda 返回Task<bool>(不需要async/await需要,因为Post已经返回Task<bool>),以及运行 lambda 的更新方法。

Personally, I find the first option (above) simpler, and suspect it is more likely what you want. Given your API already returns Task<T>, you can just pass that around and awaitit directly.

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