我正在阅读有关BlockingCollection(并发集合的特定示例)的信息,并遇到了一个演示其工作原理的小程序。这个程序使我的输入加倍(无论我按回车时输入的内容是加倍的),它会一直这样直到输入空格。
我的问题是,为什么程序在第一行“ while(true)”处不阻塞?
我的猜测是,在没有要从集合中删除的元素时,BlockingCollection会阻止读取的Task,因此我认为一旦col.Add(s)发生,由于元素可用,它会再次释放。
第二,当输入空格时,为什么不只是当前线程停止了(写任务的线程)?读取任务不应该永远继续等待解锁者吗?而是整个程序终止。
public static class ConcurrentCollections
{
public static void Main()
{
BlockingCollection<string> col = new BlockingCollection<string>();
Task read = Task.Run(() =>
{
while (true)
{
Console.WriteLine(col.Take());
}
});
Task write = Task.Run(() =>
{
while (true)
{
string s = Console.ReadLine();
if (string.IsNullOrWhiteSpace(s)) break;
col.Add(s);
}
});
write.Wait();
Console.ReadLine();
}
}
答案 0 :(得分:2)
为什么程序不在第一行“ while(true)”处阻塞?
因为它在单独的线程中运行。 read
和write
都在各自的线程上运行,与主线程分开。
输入空格后,为什么不只是当前线程停止了(写任务的线程)?
当前线程是write
线程。它确实结束了。但是请注意:
write.Wait();
这告诉主线程等待write
线程。但是请注意,它不会等待read
线程。因此,write
线程结束后,主线程便移至Console.ReadLine()
,后者等待enter键。按下Enter键后,主线程就会结束,这意味着整个应用程序都会结束。
read
线程一直处于打开状态,但是当主线程结束时,该进程终止,这也杀死了read
线程。