When to use TaskEx.Run and TaskEx.RunEx

I am trying to figure out when to use TaskEx.Run . I gave two code examples that I wrote below that give the same result. What I don't see is why I took the Task.RunEx approach TaskEx.RunEx , I'm sure there is a good reason and was hoping that someone could fill me up.

 async Task DoWork(CancellationToken cancelToken, IProgress<string> progress) { int i = 0; TaskEx.RunEx(async () => { while (!cancelToken.IsCancellationRequested) { progress.Report(i++.ToString()); await TaskEx.Delay(1, cancelToken); } }, cancelToken); } private void Button_Click(object sender, RoutedEventArgs e) { if (button.Content.ToString() == "Start") { button.Content = "Stop"; cts.Dispose(); cts = new CancellationTokenSource(); listBox.Items.Clear(); IProgress<string> progress = new Progress<string>(s => { listBox.Items.Add(s); listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); }); DoWork(cts.Token, progress); } else { button.Content = "Start"; cts.Cancel(); } } 

I can achieve the same results as

  async Task DoWork(CancellationToken cancelToken) { int i = 0; while (!cancelToken.IsCancellationRequested) { listBox.Items.Add(i++); listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); await TaskEx.Delay(100, cancelToken); } } private void Button_Click(object sender, RoutedEventArgs e) { if (button.Content.ToString() == "Start") { button.Content = "Stop"; cts.Dispose(); cts = new CancellationTokenSource(); listBox.Items.Clear(); DoWork(cts.Token); } else { button.Content = "Start"; cts.Cancel(); } } 
+7
source share
3 answers

Use TaskEx.Run if you want to run synchronous code in the context of a thread pool.

Use TaskEx.RunEx if you want to run asynchronous code in the context of a thread pool.

Stephen Tub has two blog entries related to the difference in behavior:

This is just one of several options for creating tasks . If you do not need to use Run / RunEx , you should not. Use simple async methods and use Run / RunEx if you need to run something in the background.

+11
source

The difference between the two DoWork() methods is that the first (which uses TaskEx.RunEx() ) is not asynchronous at all. It runs completely synchronously, starts another task in another thread, and immediately returns the completed Task . If you selected await ed or Wait() for this task, it did not wait for the completion of the internal task.

+1
source

Task.Run generates a new thread in most scenarios, as I understand it.

It is important to note that simply because you mark the async method and use awaiters, this does NOT (necessarily) mean that new threads are created, improvements are scheduled in the SAME, the executable from which they were called from in many cases.

The trick here is related to the SchedulingContext. If it is installed for a multi-threaded apartment, then you are going to delegate the improvements to viable threads in threadpool. If you are in a single-threaded apartment, since all the user interfaces are WPF and WinForms, then it will return to the calling thread to complete, which allows you to work directly in the user interface without visible sorting of lines in the code.

0
source

All Articles