После ввода l oop после ваших вызовов Join()
потоки уже будут завершены к тому времени, как вы проверите консоль на предмет ввода, поэтому вам придется изменить порядок.
Далее, while
l oop будет введен и продолжит работу, только если есть доступный ключ, и он T
. Требуется обратное: l oop до доступна клавиша, и она T
.
Наконец, Console.ReadKey()
блокируется до нажатия клавиши, поэтому вы не сможете нужно также проверить Console.KeyAvailable
, если вы не хотите делать что-то еще, пока вы ждете T
(например, показать прогресс или проверить, завершены ли потоки самостоятельно).
while (Console.ReadKey(true).Key != ConsoleKey.T)
{
// Do nothing...
}
// T has been pressed
// Signal to the threads to stop
// Set a flag, Cancel() a CancellationTokenSource, etc.
// Wait for the threads to terminate
threadProdutor.Join();
threadConsumidor.Join();
// Exit the program
Environment.Exit(0);
Для отображения пока вы ждете нажатия клавиши прерывания, вы можете переписать l oop следующим образом ...
TimeSpan progressInterval = TimeSpan.FromSeconds(1);
// complete is a simple flag set by the consumer(s)
// Only call ReadKey() when KeyAvailable so it can't block longer than updateInterval
while (!complete && (!Console.KeyAvailable || Console.ReadKey(true).Key != ConsoleKey.T))
{
Console.WriteLine($"Current time is {DateTime.Now:HH:mm:ss.fff}");
Thread.Sleep(progressInterval);
}
Обратите внимание, что у этого недостатка всегда спит весь progressInterval
, даже если условие выхода было выполнено до этого. Простой обходной путь - сократить время между проверками до 1 / n
, а затем отображать прогресс только после каждой n
th проверки ...
TimeSpan progressInterval = TimeSpan.FromSeconds(1);
const int ReadsPerProgressInterval = 10;
TimeSpan sleepTimeout = new TimeSpan(progressInterval.Ticks / ReadsPerProgressInterval);
int readCount = 0;
// complete is a simple flag set by the consumer(s)
// Only call ReadKey() when KeyAvailable so it can't block longer than updateInterval
while (!complete && (!Console.KeyAvailable || Console.ReadKey(true).Key != ConsoleKey.T))
{
// This won't display progress until after progressInterval has elapsed
// To display initial progress:
// A) change to == 1, or...
// B) duplicate progress display to before the loop as well
if (++readCount % ReadsPerProgressInterval == 0)
Console.WriteLine($"Current time is {DateTime.Now:HH:mm:ss.fff}");
Thread.Sleep(sleepTimeout);
}