C # выходит из блока using () с потоком, все еще работающим на объекте с заданной областью

Что происходит с потоком, если он запускает метод в объекте, который был освобожден путем выхода из блока using?
Пример:

    using (SomeObject obj = new SomeObject ())
    {
      obj.param = 10 ;
      Thread newThread = new Thread(() => { obj.Work(); });
      newThread.Start();
    }
    ... 
 

obj.Work () выполняется в новом потоке, но obj - это объект IDisposable, который обычно освобождается при выходе из блока using. Что произойдет, если поток продолжит работу после завершения блока using? Будет ли объект удален только после завершения потока? Или нить оборвется?

Спасибо.


person yitz    schedule 23.06.2009    source источник
comment
Вместо того, чтобы иметь оператор using вне потока, поместите его внутри потока. Тема newThread = новая тема (() = ›{using (SomeObject obj = new SomeObject ()) {obj.param = 10; obj.Work ();}}); newThread.Start ();   -  person Relster    schedule 23.06.2009


Ответы (4)


Произойдут интересные вещи.

В частности, метод dispose для SomeObject будет вызываться либо до, либо после того, как Work был вызван, поскольку он мог или не мог быть запланирован для запуска к этой точке.

После этого это зависит от того, что делает метод dispose SomeObject; если он, скажем, освобождает SqlConnection, который не используется в «Работе», тогда проблем быть не должно; Однако если SomeObject ожидает, что он не был удален, вы, вероятно, получите исключение в этом потоке.

person CoderTao    schedule 23.06.2009
comment
Почему-то это заставляет меня думать о Мос Деф в «Итальянской работе»: у меня был неудачный опыт. - person Robert Rossney; 24.06.2009

Помните, что IDisposable - это просто шаблон и не освобождает память, связанную с объектом. В этом случае закрытие блока using вызовет obj.Dispose, а другой поток, использующий obj, продолжит выполнение.

Это создаст для вас странные проблемы, поскольку состояние obj's может быть изменено, пока другой поток его использует (все зависит от того, как реализован метод Dispose). Излишне говорить, что это применение IDisposable, потоковой передачи и оператора using будет в лучшем случае проблематичным.

person Andrew Hare    schedule 23.06.2009

Объект вызовет Dispose в конце блока. Он продолжит работу, но obj станет нестабильным, поскольку Dispose предполагает закрытие соединений и т. Д. Теперь возможно, что obj будет настроен, чтобы проверять, используется ли что-то, и закрывать его впоследствии, но я бы не стал на это рассчитывать, если только вы написали объект, чтобы справиться с этим.

person kemiller2002    schedule 23.06.2009

Когда блок using выходит из основного потока, он вызывает .Dispose () объект, что может вызвать всевозможные забавные проблемы с параллелизмом. Однако объект не будет собираться сборщиком мусора - он останется, но в недопустимом состоянии, в зависимости от вашей реализации .Dispose ().

person Matt    schedule 23.06.2009