【发布时间】:2013-04-07 14:29:57
【问题描述】:
我知道TPL 是面向任务的,而经典的线程模型是面向工人的。 任务让您主要关注要解决的问题,而不是如何解决问题的机制 它会完成的。。但是说到线程和任务的关系,我还是有点迷茫。
下面是演示代码:
namespace AsyncUnderTheHood
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main Start : {0}", Thread.CurrentThread.ManagedThreadId);
AwaitTest();
Console.WriteLine("Main End : {0}", Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
public static void DoWork()
{
Console.WriteLine("DoWork Start: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Console.WriteLine("DoWork End: {0}", Thread.CurrentThread.ManagedThreadId);
}
public async static void AwaitTest()
{
Console.WriteLine("AwaitTest Start : {0}", Thread.CurrentThread.ManagedThreadId);
Task t = new Task(DoWork);
t.Start();
await t;
Console.WriteLine("AwaitTest Done : {0}", Thread.CurrentThread.ManagedThreadId);
}
}
}
输出是这样的:
Main Start : 1
AwaitTest Start : 1 <------------ A
DoWork Start: 3
Main End : 1
DoWork End: 3
AwaitTest Done : 3 <------------ B
我的问题是,为什么 A 和 B 在不同的线程上?
相同的方法在不同的线程上执行,当线程亲和性很重要时,这会导致问题吗?
【问题讨论】:
-
您在控制台应用程序中使用异步 void 方法。真的可以吗?
-
@WouterdeKort 从输出中可以看出,它确实有效(因为
ReadLine()。虽然这是一种不好的做法,不应该在生产代码中完成。 -
@WouterdeKort 它是“有效的”,因为主要是 ReadLine。如果 main 没有让应用程序像那样运行,那么您将永远无法在 async void 方法上“等待”,并且应用程序甚至可能在任务开始之前退出。不建议将 async void 方法用于事件处理程序以外的任何内容。
-
您提出这个问题,并因此与工具抗争而不是利用它,这表明您需要重新考虑您的设计和/或您对工具的理解。将您的应用程序重新考虑为由(真实的物理)人员在办公室完成的工作,与实际的数据文件夹进行通信。当该工作流程有意义时,转换回自动化解决方案。
标签: c# parallel-processing task-parallel-library async-await c#-5.0