Вопрос с внесенными в него поправками на самом деле связан не с многопоточностью, а с тем, как остановить длительные действия. Лично я всегда использую APM для длительных потоковых и коммуникационных операций, таких как передача больших файлов. Каждый обратный вызов выполняется в потоке пула завершения ввода-вывода и быстро завершается, обрабатывая скромный кусок и планируя следующий проход. Отложенные операции можно отменить, просто вызвав Close()
для объекта сокета. Это намного дешевле и эффективнее, чем самостоятельное управление потоками.
Как уже упоминалось, Abort()
- это плохая карма, и ее следует избегать.
Материал ниже был написан до исключения случая зацикливания из вопроса.
Когда долго выполняющиеся процессы зацикливаются, они должны all включать флаг выхода в состояние их цикла, чтобы вы могли дать им сигнал выйти.
bool _run; //member of service class
//in OnStart
_run = true;
//in a method on some other thread
while ((yourLoopCondition) & _run)
{
//do stuff
foreach (thing in things)
{
//do more stuff
if (!_run) break;
}
}
if (!_run) CleanUp();
//in OnStop
_run = false;
Строго говоря, вы должны использовать летучие вещества, но поскольку только логика управления устанавливает флаг, это не имеет значения. Технически, существует состояние гонки, но это просто означает, что вы можете объехать еще раз.