poc*_*oco 8 c# wpf task-parallel-library async-await async-ctp
我想知道何时使用TaskEx.Run.我提供了下面写的两个代码示例,它们产生相同的结果.我没有看到为什么我会采取Task.RunEx TaskEx.RunEx方法,我确信有一个很好的理由,并希望有人可以填补我.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样取得同样的结果
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();
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解,Task.Run 在大多数情况下都会生成一个新线程。
需要注意的是,仅仅因为您将方法标记为异步并使用等待程序,这并不(必然)意味着正在创建新线程,在许多情况下,完成会安排在调用它们的同一执行线程上。
这里的技巧与 SchedulingContext 有关。如果它是为多线程单元设置的,那么您将把完成委托给线程池上的可行线程。如果您像所有 WPF 和 WinForms UI 代码一样处于单线程单元中,那么它将返回到调用线程以完成操作,从而允许直接在 UI 上完成工作,而无需在代码中进行可见的线程编组。
| 归档时间: |
|
| 查看次数: |
12613 次 |
| 最近记录: |