0

I have an input array that I need to produce an output that is in the same order. If I run

source.Select((item, index) =>
  remoteDb.Where(condition).FirstOrDefaultAsync()
    .ContinueWith(result -> /* Manipulate and save to outArray */));

Do I have any guarantee that ContinueWith() will execute in the same order as the source array? Basically, can I save with outArray.append(result), or will I need to use outArray[index] = result to save it in the appropriate order?

Trevortni
  • 688
  • 8
  • 23
  • 1
    When you tested it, what did you observe? – Enigmativity Sep 30 '21 at 22:59
  • I really doubt it will be in your desired order by default. I tried something similar. But this LINQ-Query should be optimized. This doesn't look healthy. – ˈvɔlə Sep 30 '21 at 23:03
  • The tasks will be created in the order of the input array, but there is absolutely no guarantee they will complete in that order. If remoteDb is something like Entity Framework, then it [won't work at all](https://stackoverflow.com/q/24702183/11683). – GSerg Sep 30 '21 at 23:07
  • @GSerg: Yeah, the error predicted in the top answer is exactly what I'm seeing: `A second operation started on this context before a previous asynchronous operation completed.` I've stripped out the `ContinueWith()` and am trying it with just `outArray = Select( => Where().FirstOrDefaultAsync()).ToArray();` Hoping that gives me what I need. – Trevortni Sep 30 '21 at 23:23
  • No, it won't. It's the `.FirstOrDefaultAsync` that does it, not the `.ContinueWith`. Just use the non-async `.FirstOrDefault`. – GSerg Sep 30 '21 at 23:29
  • 2
    Side note: ideally you just keep such crazy ideas of mixing all ways to make code asynchronous to your privately used code... There is very small number of people who can reason about mixing Tasks, await, and ContinueWith and even less who get it right. I'd strongly recommend sticking with far more common `await` and `Task.WhenAll`.... – Alexei Levenkov Sep 30 '21 at 23:29
  • And it turns out that even there I have to use the synchronous version of `FirstOrDefault`. I couldn't find anywhere to put my `async` and `await` to work with the async version. – Trevortni Sep 30 '21 at 23:39
  • Which apparently SO didn't notify me you had already told me. – Trevortni Sep 30 '21 at 23:41
  • @AlexeiLevenkov: Actually, this was all wrapped in a `WhenAll`; I just didn't include it in the question because it didn't seem relevant to what was happening, as it never even got touched. And now it's gone. – Trevortni Sep 30 '21 at 23:45
  • You cannot use WhenAll with EF. It just not thread safe. – Svyatoslav Danyliv Oct 01 '21 at 05:06
  • @Trevortni - You could `await` the `.FirstOrDefault` with `Task.Run(() => ... )` if you want to push it to a task, but keep the order. – Enigmativity Oct 01 '21 at 06:46

0 Answers0