Почему прерывание завершает всю программу, а не только текущий поток - PullRequest
0 голосов
/ 04 ноября 2018

Я читал о BlockingCollection (конкретный пример одновременных коллекций) и наткнулся на эту небольшую программу, которая демонстрирует, как они работают. Эта программа удваивает мой ввод (все, что я набираю, удваивается, когда я нажимаю клавишу ввода), и так продолжается до тех пор, пока я не введу пробел.

Мой вопрос: почему программа не блокирует первую строку «while (true)»?

Я предполагаю, что BlockingCollection блокирует задачу чтения, когда нет элемента, который нужно удалить из коллекции, поэтому я предполагаю, что он освобождается снова после того, как произойдет 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();
    }
}

1 Ответ

0 голосов
/ 04 ноября 2018

почему программа не блокирует первую строку "while (true)"?

Потому что он работает в отдельном потоке. И read, и write работают в своих собственных потоках, отдельно от основного потока.

при вводе пробела почему не останавливается только текущий поток (тот, у которого есть задача записи)?

Текущий поток - это поток write. Это конец. Но обратите внимание:

write.Wait();

Это говорит основному потоку ждать потока write. Но обратите внимание, что он не ждет потока read. Таким образом, как только поток write заканчивается, основной поток переходит к Console.ReadLine(), который ожидает клавишу ввода. И как только вы нажмете ввод, основной поток завершится, что означает, что завершается все приложение.

Поток read остается открытым все время, но когда основной поток заканчивается, процесс завершается, что также убивает поток read.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...