Skip to content

Conversation

@StephenCleary
Copy link

This code shows the basic pattern of doing parallel work and also keeping the UI updated. Specifically:

  • Use await Task.Run(() => ... parallel code ...); to push the parallel work off the UI thread.
    • Parallel, PLINQ, etc. all use the calling thread as one of their worker threads, so this doesn't work well with the UI thread. The Task.Run pushes all the parallel work off the UI thread and onto the thread pool.
    • But just Task.Run has a fire-and-forget problem; specifically, any exceptions would be ignored. Using await Task.Run makes the UI thread observe the background work for completion/exceptions/results.
  • Propagate async/await in the UI code up from that point.
  • Use IProgress<T>/Progress<T> for progress updates. This is cleaner than the sub-task approach (StartNew with UI TaskScheduler) because:
    • No background code is aware of UI elements, or the code needed to update the UI. As far as the code in the Parallel.ForEach is concerned, it's only sending updates to its caller, which could be a UI, Console window, or WebSocket as far as it cares. Or they could just be ignored, if you wanted to do a headless comparison.
    • No need to mess with the low-level TaskScheduler type. Progress<T> handles the thread marshaling implicitly.

@StephenCleary
Copy link
Author

StephenCleary commented Dec 26, 2017

The result on my machine has the non-parallel version running faster, but that could be due to the way the thread pool is being fought over by both parallel algorithms running, er, in parallel. It appears that the brute force approach is saturating the thread pool and preventing Parallel from operating optimally.

When I run them one at a time, they both take the same amount of time (22 seconds for me).

@jeremybytes
Copy link
Owner

Thank you for the contribution, Stephen. Using progress reporting makes a lot of sense, particularly because of the UI thread management that you mentioned. I wouldn't have thought of that. I'll do a write up soon that includes your code in an upcoming article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants