Pattern for doing parallel work off UI thread.#2
Open
StephenCleary wants to merge 1 commit into
Open
Conversation
Author
|
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 When I run them one at a time, they both take the same amount of time (22 seconds for me). |
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This code shows the basic pattern of doing parallel work and also keeping the UI updated. Specifically:
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. TheTask.Runpushes all the parallel work off the UI thread and onto the thread pool.Task.Runhas a fire-and-forget problem; specifically, any exceptions would be ignored. Usingawait Task.Runmakes the UI thread observe the background work for completion/exceptions/results.async/awaitin the UI code up from that point.IProgress<T>/Progress<T>for progress updates. This is cleaner than the sub-task approach (StartNewwith UITaskScheduler) because:Parallel.ForEachis 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.TaskSchedulertype.Progress<T>handles the thread marshaling implicitly.