Утилизировать WATHANDLE для базовой резьбы синхронизации

StackOverflow https://stackoverflow.com//questions/23039999

  •  21-12-2019
  •  | 
  •  

Вопрос

Согласно документации, WATHANDLE в .NET должна быть явно / неявно расположена.Однако у меня проблемы с достижением этого для следующей основной задачи синхронизации:

    .
  • Потребляемая задача выполняется в потоке.
  • Основная поток ждет задачи для выполнения предопределенного периода времени.Основная нить должна продолжаться, если A.Задача завершена или б.Тайм-аут произошел.

Здесь моя попытка использовать объект autoresetevent:

using(var waitHandle = new AutoResetEvent(false)){
    var worker = new Thread(() =>
    {
        try
        {
            TimeConsumingTask();
            waitHandle.Set(); //throws System.ObjectDisposedException: Safe handle has been closed
        }
        catch (Exception e)
        {...}
    }) {IsBackground = true};
    worker.Start(); //start worker

    const int waitTimeInMs = 5000; 
    var signaled = waitHandle.WaitOne(waitTimeInMs);//block main thread here. 
    if (!signaled)
    { //if timed out
       worker.Interrupt();
    }
}
.

Существует очевидное состояние гонки, где основная нить ждет времена и утилизирует объект обработки ожидания, который вызывает исключение ObjectDisposedException.Есть ли другой способ, которым я устанавливаю это так, чтобы ручка правильно расположена и не вызывая исключения?

Это было полезно?

Решение

Конечно, нет приличного способа сделать это. Примечание вверх по спереди, что вы нарисовали себя в этот угол, по сути, оставив нить, бегущую дикую, ничего особенного в этом.

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

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

Сравните это с классом с менее смелым дизайном, класс задач имеет метод dispose (). Который, как нить, почти так же сложно позвонить. Руководство от .NET Guurus Просто не беспокоиться.

То же самое здесь.

Другие советы

WATHANDLE располагает, потому что ваша съемка призывает немедленно призывать новую резьбу возврата, вызывая утилизацию WATHANDLE.

Что вы должны сделать, это явно позвоните утилизацию после завершения работы вместо вашего использования оператора:

waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
   worker.Interrupt();
}
waitHandle.Dispose();
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top