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
Passing an *Awaitable* Anonymous Function as a Parameter
提问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它。

