【发布时间】:2017-02-09 20:24:51
【问题描述】:
我一直在尝试确定与我的其余代码同时/并行运行代码的最佳方式,可能使用线程。根据我的阅读,在现代 C# 中使用 Thread 类型是禁忌。最初我以为Parallel.Invoke(),但结果证明这是一个阻塞调用,直到所有内部工作完成。
在我的应用程序中,我不需要等待任何事情完成,我不关心得到结果,我需要完全独立于当前线程的代码。基本上是“一劳永逸”的想法。
据我所知,Task.Factory.StartNew() 是与当前运行的代码同时/并行运行一段代码的正确方法。
基于此,我认为下面的代码会随机打印出“ABABBABABAA”。
void Main()
{
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
Console.Write("A");
}
});
for (int i = 0; i < 10; i++)
{
Console.Write("B");
}
}
但是,它:
- 打印出“BBBBBBBBBBAAAAAAAAAA”
- 如果我将 Task.Factory.StartNew 与
for交换,反之亦然,打印出相同的序列,这看起来很奇怪。
所以这让我认为Task.Factory.StartNew() 从来没有真正将工作安排到另一个线程,就好像调用StartNew 是一个阻塞调用。
考虑到我不需要得到任何结果或等待/await,我是否更容易创建一个新的Thread 并在那里运行我的代码?我对此的唯一问题是使用Thread 似乎与现代最佳实践相反,而“C# 6.0 中的并发”一书指出:
只要你输入 new Thread(),就结束了;您的项目已有旧代码
【问题讨论】:
-
输出没有什么奇怪的。任务“将在之后的某个时间运行”它被安排。这次恰好是在内联循环运行之后(因为它是在任务安排后立即运行的)并且测试代码没有显示任何有趣的内容。在这两种情况下,在每次循环迭代之间添加 100 毫秒的延迟应该会改变观察结果。
-
嗯,我明白了。我将循环更改为具有更高的值,现在我看到了很多 AAAAABBBBBAAAA。那么是不是我根本没有给任务安排足够的时间?
-
在这种情况下 - 是的。此外,大多数线程实际上是交错运行的,而不是真正并发的(这在 1 核系统上可视化是最简单的;尽管 n 核处理器仍将运行 m 个线程,其中 m >>> n)。
标签: c# multithreading parallel-processing task-parallel-library task