Как правильно остановить Thread?

330
26 декабря 2016, 22:30

Язык C#, Visual Studio 2013. Скажите пожалуйста, как в консольном приложении обработать нажатия клавиши, чтобы остановить работающий Thread? Не могу найти класса с соответствующим событием, именно, для консольного приложения.

Answer 1

Никак. Thread должен сотрудничать, и сам останавливаться, когда его попросят.

Например, при помощи разделяемой переменной (но не забудьте о синхронизации при помощи lock):

object mutex = new object();
bool stop = false;
var t = new Thread(() =>
{
    int i = 0;
    while (true)
    {
        Thread.Sleep(500);
        // тут сделать что-то полезное, например:
        Console.WriteLine(i++);
        // проверка на выход
        lock (mutex)
        {
            if (stop)
                break;
        }
    }
});
t.Start();
Console.ReadKey();
lock (mutex) stop = true;
t.Join();

Вот вам более современный метод, без Thread и Sleep, через Task и CancellationToken:

static void Main(string[] args)
{
    CancellationTokenSource cts = new CancellationTokenSource();
    var task = Task.Run(() => Work(cts.Token));
    Console.ReadKey();
    cts.Cancel();
    task.Wait(); // для асинхронной функции тут лучше await task
}
static async Task Work(CancellationToken ct)
{
    try
    {
        int i = 0;
        while (!ct.IsCancellationRequested)
        {
            await Task.Delay(500, ct);
            Console.WriteLine(i++);
            // после длинных операций внутри цикла имеет смысл вставлять
            //if (ct.IsCancellationRequested)
            //    return;
        }
    }
    catch (OperationCanceledException ex)
    {
        // нас останавливают, выходим
    }
}

CancellationToken — это правильный метод передавать сообщения о завершении, используйте его по возможности.

Спасибо @rdorn и @Pavel Mayorov за подсказки в комментариях, которые помогли значительно улучшить ответ.

READ ALSO
Вывод информации о выполнении в PowerShell

Вывод информации о выполнении в PowerShell

Добрый деньИмеется файл написанный на C#, например 'app

390
Обновление данных в таблице. Entity Framework

Обновление данных в таблице. Entity Framework

Есть сущности, получаемые вне контекстаИх нужно обновить в бд (если есть изменения)

685
Удаление элемента списка

Удаление элемента списка

Каким образом можно удалить элемент списка, зная лишь его значениеНапример,

481
данный ключ отсутствует в словаре

данный ключ отсутствует в словаре

Выдает ошибку "данный ключ отсутствует в словаре" при нажатии на Q,W

644