简体   繁体   中英

Why to split the tasks not running on UI thread to make WPF app more responsive?

In part1 "Getting Started" of

  • Alexandra Rusina's series. Parallel Programming in .NET Framework 4

in order to make WPF UI responsive, it is done by outsourcing the intensive computations out of UI. Eventually, the code was changed to:

for (int i = 2; i < 20; i++)
 {
     var t = Task.Factory.StartNew(() =>
     {
         var result = SumRootN(i);
         this.Dispatcher.BeginInvoke(new Action(() =>
             textBlock1.Text += "root " + i.ToString() + " " + 
                result.ToString() + Environment.NewLine)
             ,null);
     });
 }

Update: so shifting the intensive computations out of UI thread.

Here are the quotes from Part1 article upon coming to this snippet:

  • "To make the UI responsive, I am going to use tasks, which is a new concept introduced by the Task Parallel Library. A task represents an asynchronous operation that is often run on a separate thread"
  • "Compile, run… Well, UI is responsive"

And in order to output to WPF UI from those separate task threads (or to avoid InvalidOperationException that says “The calling thread cannot access this object because a different thread owns it.”) the Dispatcher.BeginInvoke() was engaged.

Part2 of the same series "Parallel Programming: Task Schedulers and Synchronization Context" tells about the same snippet of code (after small change of introducing a local iteration variable):

"This one requires more thorough refactoring. I can't run all the tasks on the UI thread, because they perform long-running operations and this will make my UI freeze. Furthermore, it will cancel all parallelization benefits, because there is only one UI thread.

What I can do is to split each task into..."

Does not the part1-article contradict to the part2-article ?

What is the need of splitting the tasks that are not running on UI thread into parts?

What do I undermisoverstand here?

I think there are two different concepts here. Part 1 talks about running code in tasks as to not block the UI thread. Part 2 talks about running several tasks in parallel. One is used to "Not block the UI thread" and the other is used to get more things done in parallel. If you have only two threads: the UI thread and the task thread, things are not happening in parallel and you are not leveraging the true power of parallel processing.

The statements don't contradict, they are quite adding up to a whole.
The UI-thread is responsible for refreshing the window and the controls in it, so the react when you activate them, go over them with the mouse cursor, etc.
If you would perform a long-running operation, for example a for-loop with 10000 iterations, the UI would freeze and become unresponsive (the window will blur and the little blue donut of death will come up). Once the for-loop has completed, your UI will be there again.
In order to relieve the UI-thread from additional burden, you put long-running tasks in seperate threads/tasks, so they execute concurrently. Your UI will stay responsive and accept commands (clicks, keystrokes, ...). Maybe unrelated but grappling on the basics behind it

Users expect an app to remain responsive while it does computation, regardless of the type of machine. This means different things for different apps. For some this translates to providing more realistic physics, loading data from disk or the web faster, quickly presenting complex scenes and navigating between pages, finding directions in a snap, or rapidly processing data. Regardless of the type of computation, users want their app to act on their input and eliminate instances where it appears suspended while it “thinks.”

Read this article here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM