对我问题的评论表明,"同步上下文"是决定任务是作为单独的线程还是在一个线程上运行,但这在这个问题的任何回答中都没有提到,也没有提到任务何时实际在单独的线程上并行运行,或者只是在同一线程上运行,但在等待IO时可能在它们之间共享工作。
特别是,我正在寻找Thread
对象和Task
对象之间的比较,无论它们的行为相同还是不同。
异步"和"等待"如何连接(或不连接)也会有所帮助。
举个说明性示例,假设我有两个操作:
f
:非 IO 循环繁忙一秒钟g
:休眠一秒钟
让我们假设我有一个内核数量惊人的 CPU。
给定以下代码,无论是h = f
还是h = g
,运行 yes 应该需要接近一秒钟?
Thread x1 = new Thread(h);
Thread x2 = new Thread(h);
Thread x3 = new Thread(h);
Thread x4 = new Thread(h);
Thread x5 = new Thread(h);
x1.Start();
x2.Start();
x3.Start();
x4.Start();
x5.Start();
x1.Join();
x2.Join();
x3.Join();
x4.Join();
x5.Join();
假设我对任务做了类似的事情:
Task x1 = new Task(h);
Task x2 = new Task(h);
Task x3 = new Task(h);
Task x4 = new Task(h);
Task x5 = new Task(h);
x1.Start();
x2.Start();
x3.Start();
x4.Start();
x5.Start();
x1.Wait();
x2.Wait();
x3.Wait();
x4.Wait();
x5.Wait();
对于h = f
和h = g
的情况,此任务代码需要多长时间才能运行,如果取决于,哪些情况会有所不同,我该如何控制它们?
特别是,我正在寻找在此上下文中 Thread 对象和 Task 对象之间的比较,无论它们的行为相同还是不同。
它们几乎与您拥有的代码相同。
有两种不同类型的任务:运行代码的委托任务和代表未来的承诺任务。
使用Task
构造函数和Start
创建的任务是委托任务。使用async
和await
创建的任务是承诺任务。
委托任务仅表示要运行的代码。它们与线程不同,但它们确实在线程上运行。使用您的示例代码,Start
将启动这些在TaskScheduler.Current
上运行的任务,这可能与TaskScheduler.Default
相同,这意味着它们将在线程池上运行。由于您假设内核数量过多,因此您的委托任务代码与手动线程代码基本相同,只是它们在线程池线程上运行,而不是在您自己的线程上运行。
附带说明一下,使用Task
构造函数和Start
是如此低级,以至于它甚至没有任何用例;你永远不应该使用Task
构造函数,因为无论你试图做什么,总有更好的解决方案。 查看任务并行库文档中的更高级别基元。在您的情况下,您可以使用一行代码执行相同的操作:
Parallel.Invoke(h, h, h, h, h);