【问题标题】:Await method with Func<T, TResult> Delegate as parameter: compilation error以 Func<T, TResult> Delegate 作为参数的等待方法:编译错误
【发布时间】:2013-06-06 04:01:43
【问题描述】:

初始声明

我想异步调用一个操作,我将委托作为参数传递给该操作(详情如下)。编译器给我一个错误。有人能指出我正确的方向吗?

异步函数:

private async Task<Route> FindRouteAsync(Destination Destination, 
                                         Func<Destination, bool> predicate){...
List<Destination> _Destinations = __Route.Destinations.Where(predicate).ToList();
...}

调用代码:

private async Task<List<Route>> FindRoutesAsync(Destination[] Destinations){...
    Route _DestinationRoute = await FindRouteAsync(__Destination, 
                                               d => d == __Destination);
    ...}

编译错误:

“await”运算符只能在异步 lambda 表达式中使用。考虑用 'async' 修饰符标记这个 lambda 表达式。

更新声明 1

@svick、@Stephen Cleary:谢谢你们!你是对的,问题正如你在外循环中所期望的那样: 我所拥有的是(简化的):

Parallel.ForEach<Destination>(Destinations, __Destination =>
{
    Route _DestinationRoute = await FindRouteAsync(__Destination, 
                                                   d => d == __Destination);
}

由于这个 lambda 表达式__Destination =&gt; {...},代码无法编译。我把它变成了__Destination =&gt; async {...},现在它可以工作了。

现在看起来像这样:

Parallel.ForEach<Destination>(Destinations, async __Destination =>
{
    try
    {
        // First, try to find an exact match
        Route _DestinationRoute = await FindRouteAsync(__Destination, d => d == __Destination);
        if (_DestinationRoute.ConnectionId != 0)
        { _DestinationRoutes.Enqueue(_DestinationRoute); }
        ...
    }
    catch...
});

所以我只是在我的代码中查看了错误的 lambda 表达式。另一个引起了所有人的大惊小怪。 再次感谢你!经验教训:“不要对未来的假设跳得太快”。

PS:这是我第一次来这里,也许你可以帮助我在到期时给予信用。我认为 svick、Stephen Cleary 和 Javalsu 的贡献很有帮助。现在我该怎么做?平心而论,svick 的评论引导我进行代码分析,最终向我显示了错误。

更新声明 2

似乎Parallel.ForEachawait 在循环内的整个构造存在缺陷,并且该解决方案成功的机会很小。更多细节可以在这里找到:Nesting await in Parallel foreach

【问题讨论】:

  • 请检查__Destination的类型。我怀疑是Destination[] 而不是Destination
  • 您能否提供一个简短但完整的示例代码来显示您的错误?我认为问题出在您遗漏的部分。
  • @lulian:@svick 是正确的;您发布的错误是抱怨在 lambda 表达式中使用 await,但您没有发布任何在 lambda 表达式中使用 await 的代码。
  • 您更新后的代码不会像您预期的那样工作。 Parallel.ForEach() 不适用于 async
  • @svick:我没有意识到这是个问题。经过一番搜索,我发现了一个类似的问题:Nesting await in Parallel foreach。在那里,指出了Parallel.ForEachasync-await 问题并提出了解决方案(实际上由您提出)。对我来说,现在有点过头了,所以我可能会从 Parallel.Foreach 块中删除 await。感谢您的宝贵时间!

标签: c# lambda async-await func


【解决方案1】:

尝试将其更改为以下内容

private async Task<List<Route>> FindRoutesAsync(Destination[] Destinations){...
    Route _DestinationRoute = await FindRouteAsync(__Destination, 
                                               async d => d == __Destination);
    ...}

我不在办公桌附近,所以无法对其进行测试。

【讨论】:

  • 这不可能,async lambda,不能返回bool(只能返回Task&lt;bool&gt;)。
  • @Kaveh Shahbazian:__Destination 的类型是 Destination。当代码被称为同步时,它运行正常。我试图把它变成异步的,我不知道怎么做。
  • @Javalsu:有趣或令人惊讶...错误没有改变!
  • @svick:我不认为发布整个代码会有帮助。即使我发布的代码是完整的代码,同样的问题仍然存在。想象一下调用代码就是这样做的(好吧,再加上一个额外的return new List&lt;Route&gt;() { _DestinationRoute })。对于异步函数,想象它只使用类属性 __Route 执行声明的行,最后返回。
  • @Iulian 我并不是说您应该发布所有代码,而是您应该发布能够重现您的错误的短代码。您可以从您的代码开始,然后删除与错误无关的所有内容。问题是您发布的代码没有重现错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多