Шаблон тайм-аута - Насколько плохо Thread.Abort на самом деле? - PullRequest
5 голосов
/ 02 апреля 2009

Я читал на разных сайтах, что Thread.Abort не очень хорош в использовании. В этом случае, как реализовать шаблон тайм-аута? Например, я читал, что MS использует шаблон ниже (который я обернул в методе расширения) по всей структуре. Лично я думаю, что это довольно классное расширение, но я беспокоюсь о Thread.Abort. У кого-нибудь есть способ получше?

 public static bool CallandWait(this Action action, int timeout)
    {
        Thread subThread = null;
        Action wrappedAction = () =>
        {
            subThread = Thread.CurrentThread;
            action();
        };

        IAsyncResult result = wrappedAction.BeginInvoke(null, null);

        if (((timeout != -1) && !result.IsCompleted) && (!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted))
        {
            if (subThread != null)
            {
                subThread.Abort();
            }

            return false;
        }
        else
        {
            wrappedAction.EndInvoke(result);
            return true;
        }
    }

Ответы [ 3 ]

13 голосов
/ 02 апреля 2009

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

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

10 голосов
/ 02 апреля 2009

Потенциально очень плохо.

Прерванный поток может привести к повреждению общего состояния, к выполнению асинхронных операций, ...

См. Блог Джо Даффи: "Управляемый код и усиление асинхронных исключений" .

2 голосов
/ 02 апреля 2009

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

Чтобы закрыть его должным образом, вы даете ему сигнал прекратить то, что он делает, вызывая метод или устанавливая свойство, затем выполняйте Thread.Join, чтобы дождаться его закрытия, прежде чем закрыть приложение или перейти к другим задачам.

...