-1

Initial Statement

I would like to call asynchronously an operation to which I pass a delegate as a parameter (details below). The compiler gives me an error. Could someone point me in the right direction?

Async function:

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

Calling code:

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

The compilation error:

The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.

Updated Statement 1

@svick, @Stephen Cleary: Thank you guys! You were right, the problem was just as you expected in an outer loop: What I had was (simplified):

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

Because of this lambda expression __Destination => {...} the code wouldn't compile. I turned it into __Destination => async {...} and now it works.

Now it looks like this:

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

So I was just looking at the wrong lambda expression in my code. The other one was causing all the fuss. Thank you again! Lesson learned: "don't jump so fast to assumptions in the future".

PS: it's my first time here and maybe you can help me with giving credit where is due. I think the contributions from svick, Stephen Cleary and (in perspective) Javalsu were helpful. What do I do now? In all fairness, svick's comment led me to the code analysis that showed me the error in the end.

Updated Statement 2

It seems the whole construct of Parallel.ForEach with await inside the loop was flawed and the solution had poor chances of success. More details can be found here: Nesting await in Parallel foreach.

Community
  • 1
  • 1
Iulian
  • 11
  • 2
  • 1
    Please check what is the type of `__Destination`. I suspect it is `Destination[]` rather than `Destination`. – Kaveh Shahbazian Jun 05 '13 at 11:51
  • 2
    Could you include a short, but *complete* sample code that shows your error? I think the issue is in the parts you left out. – svick Jun 05 '13 at 12:02
  • 1
    @lulian: @svick is correct; the error you posted is complaining about using an `await` inside a lambda expression, but you did not post any code that uses an `await` inside a lambda expression. – Stephen Cleary Jun 05 '13 at 13:56
  • Your updated code won't work as you would expect. `Parallel.ForEach()` doesn't work well with `async`. – svick Jun 05 '13 at 19:04
  • @svick: I didn't realize this is a problem. After a bit more search, I found somewhat a similar question: [Nesting await in Parallel foreach](http://stackoverflow.com/questions/11564506/nesting-await-in-parallel-foreach). In there, the `Parallel.ForEach` and `async`-`await` problem is pointed out and a solution is presented (in fact by you). For me, it's a bit over my head now so I'll probably remove the `await` from inside the `Parallel.Foreach` block. Thank you for your time! – Iulian Jun 05 '13 at 19:57

1 Answers1

-2

Try changing it to the following

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

I'm not near my desk so I can't test it.

Smeegs
  • 9,151
  • 5
  • 42
  • 78
  • There is no way this could work, `async` lambda, can't return `bool` (it could only return `Task`). – svick Jun 05 '13 at 12:07
  • @Kaveh Shahbazian: The __Destination is of type Destination. When the code was called synchronous, it was running ok. I'm trying to turn it into asynchronous and I can't figure out how. – Iulian Jun 05 '13 at 12:10
  • @Javalsu: Interestingly enough or surprisingly... the error has not changed! – Iulian Jun 05 '13 at 12:11
  • @svick: I don't think posting the whole code would be helpful. The same issue is still there even if the code that I posted is the complete code. Just imagine the calling code does just that (well, plus an extra `return new List() { _DestinationRoute }`). And for the async function imagine it does only the line stated, using the class property __Route, with the eventual return at the end. – Iulian Jun 05 '13 at 12:19
  • 2
    @Iulian I'm not saying you should post all your code, but that you should post short code that reproduces your error. You can get that by starting with your code and then removing everything that's not relevant to the error. The problem is that the code you posted **does not reproduce the error**. – svick Jun 05 '13 at 12:51