I'm trying to understand when to use TaskEx.Run
. I have provided two code sample i wrote below that produce the same result. What i fail to see is why i would take the Task.RunEx TaskEx.RunEx
approach, I'm sure there is a good reason and was hoping someone could fill me in.
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 like so
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();
}
}
Use TaskEx.Run
when you want to run synchronous code in a thread pool context.
Use TaskEx.RunEx
when you want to run asynchronous code in a thread pool context.
Stephen Toub has two blog posts related to the difference in behavior:
This is only one of several options you have for creating tasks. If you do not have to use Run
/RunEx
, then you should not. Use simple async
methods, and only use Run
/RunEx
if you need to run something in the background.
The difference between your two DoWork()
methods is that the first one (that uses TaskEx.RunEx()
) is not asynchronous at all. It executes fully synchronously, starts the other task on another thread, and immediately returns a completed Task
. If you await
ed or Wait()
ed on that task, it wouldn't wait until the internal task is completed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With