Многопоточность в окнах форм C # - PullRequest
0 голосов
/ 27 октября 2011

В приложении Windows, кроме основного потока, есть другой поток, который каждую минуту выполняет долгосрочную операцию и обновляет интерфейс, используя метод Invoke.

Как мы можем завершить другой поток изящно, когда он находится в спящем состоянии?

Правильный ли выбор использования сна здесь?

Ответы [ 4 ]

4 голосов
/ 27 октября 2011

Вместо того, чтобы сделать поток один раз и затем завершить его, возможно, используйте таймер формы для запуска фонового рабочего потока каждые 60000 миллисекунд?Тогда вам вообще не нужно засыпать фоновый поток.

Это означает, что вам нужно всего лишь остановить таймер, чтобы остановить появление новых фоновых задач, но, очевидно, это не остановит ни один активный в настоящее время фоновый поток.

Потоки очень редко следует прерывать, так как не существует какого-либо замечательного механизма, позволяющего сделать это с какой-либо согласованностью.Существуют различные средства защиты, такие как критические маркеры кода.Тем не менее, я думаю, что лучше проводить длительный опрос кода для отмены, тогда вы можете написать свою собственную логику для того, чтобы покинуть корабль и вернуться рано. Примечание , это не то же самое, что принудительное прерывание потока.

Я не думаю, что сон - это правильный выбор практически при любых обстоятельствах.

Например:

private bool _askedToCancel;

public void lonRunThread()
{
    if (!_askedToCancel)
    {
        Operation1();
        Invoke(new UpdateDelegate(updateState));
    }

    if (!_askedToCancel)
    {    
        Operation2();
        Invoke(new UpdateDelegate(updateState));
    }
}

Кажется немного грязным, однако вы сохраняете очень хороший контроль над тем, какая логика выполняется, если вы отказываетесь принудительно прерывать потоки и вместо этого используете подход отмены.

Поскольку это не критичнокод, и поскольку действия над логическими значениями являются атомарными, вы должны быть в безопасности, если оба потока будут общаться с булом без какой-либо блокировки.И даже если это не по-настоящему безопасно, единственный результат - проделана дополнительная работа.

1 голос
/ 27 октября 2011

Вы всегда можете установить поток в качестве фонового потока, поэтому при выходе из приложения поток будет автоматически остановлен.

Когда вы хотите, чтобы поток был остановлен?

Если вы хотите, чтобы он остановился в середине операции, то логический флаг был бы уместен.

Так что вместо

while(true)

Вы бы сделали что-то вроде

while(exit == false)
0 голосов
/ 27 октября 2011

Нет такой вещи как грациозное завершение потока. Вместо этого ваш поток должен быть проинструктирован прекратить делать свою работу, как только он больше не нужен. Это можно сделать, создав класс для хранения параметров рабочего потока, внутри которого вы храните информацию о том, следует ли прекратить работу, и передать объект этого класса потоку.

public class WorkerParams
{
    public bool Stop = false;
}

private void TestForm_Load(object sender, EventArgs e)
{
    _thread = new Thread(lonRunThread);
    _thread.Start(new WorkerParams());
}

public void lonRunThread(object argument)
{
    WorkerParams param = argument as WorkerParams;
    DateTime lastExec = DateTime.MinValue;
    while(!param.Stop)
    {
        if (new TimeSpan(DateTime.Now.Ticks - lastExec.Ticks).TotalSeconds >= 60)
        {
            Operation1();
            Invoke(new UpdateDelegate(updateState));
            Operation2();
            Invoke(new UpdateDelegate(updateState));
            lastExec = DateTime.Now;
        }
        Thread.Sleep(500);
    }
}
0 голосов
/ 27 октября 2011

Я бы изменил while (true) в методе longRunThread и сделал бы его

while (_RunLongThread)

, а затем в TestForm я бы объявил закрытый Boolean _RunLongThread = true и установил бы его в значение false, в зависимости от того, какой метод необходимо остановитьдлительный поток.

Это «изящный» способ остановить его, то есть дождаться завершения текущей задачи, а затем завершить

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