【发布时间】:2017-08-03 05:21:04
【问题描述】:
await 不保证衍生任务继续执行同一任务:
private void TestButton_Click(object sender, RoutedEventArgs e)
{
Task.Run(async () =>
{
Debug.WriteLine("running on task " + Task.CurrentId);
await Task.Delay(TimeSpan.FromMilliseconds(100));
Debug.WriteLine("running on task " + Task.CurrentId);
});
}
这个的输出是:
running on task 1
running on task
所以我们可以看到不仅执行已经转移到另一个任务,而且还转移到了 UI 线程。我怎样才能创建一个专门的任务,并强制等待总是继续这个任务?长时间运行的任务也不会这样做。
我见过几个SynchronizationContext implementations,但到目前为止都没有工作,在这种情况下,因为它使用线程并且 System.Threading.Thread 不适用于 uwp。
【问题讨论】:
-
您似乎在这里混淆了线程和任务的概念 - 任务意味着更高、更“逻辑”的级别。没有“继续从事同一任务”的真正概念。
-
"...same thread..." - 如果您确实必须为给定任务转储当前线程,请使用
Environment.CurrentManagedThreadId。尽管在您的示例中它们将是 same -
@Benni:如果您同时从多个线程调用非线程安全 API,则只需要“大规模锁定”。除非 API 仅限于从单个线程调用,否则您从哪个线程调用无关紧要。如果 API 仅限于从单个线程调用,那么您需要仔细控制该线程,并且使用 async 和 await 可能是个坏主意。此外,您似乎将线程与任务混淆了。如果您关心用于调用 API 的线程,那么您不应该关心
Task.CurrentId。 -
线程是工人。在这个类比中,从来没有雇佣过第二个工人。但任务只是待办事项清单上的项目;是否分配给几个工人,以及这些工人如何合作决定他们如何分配,并不能改变一个工人的名字和任务的位置之间存在很大差异的事实。 -做清单。
-
我也很不清楚您为什么在事件处理程序中使用 Task.Run,以及为什么不等待返回的任务。您编写的代码和您提出的问题都很奇怪。我怀疑你有我们所说的“XY 问题”。您对如何解决问题有一些错误的想法,您是在向我们询问错误的解决方案,而不是寻求帮助解决真正的问题。使用 async-await 的预期用途:构建任务工作流。
标签: c# asynchronous task-parallel-library synchronizationcontext