Pattern for doing parallel work off UI thread. #2
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.