2009-06-23 16 views
15

¿Qué le sucede a un hilo si está ejecutando un método en un objeto que se liberó al salir de un bloque de uso?
Ejemplo:C# saliendo de un bloque using() con un hilo todavía ejecutándose en el objeto de ámbito

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

obj.Work() se ejecuta en un nuevo hilo, pero obj es un objeto IDisposable que normalmente ser liberado cuando el uso de salidas de bloque. ¿Qué sucede si el hilo continúa ejecutándose después de que finaliza el uso del bloque? ¿Se eliminará el objeto solo después de que se complete el hilo? ¿O se romperá el hilo?

Gracias.

+0

En lugar de tener la instrucción de uso fuera del hilo, póngalo dentro del hilo. Thread newThread = new Thread (() => { usando (SomeObject obj = new SomeObject()) { obj.param = 10; obj.Work(); } }); newThread.Start(); – Relster

Respuesta

4

Recuerde que IDisposable es solo un patrón y no libera la memoria asociada con el objeto. Siendo este el caso, el cierre del bloque using llamará al obj.Dispose y el otro subproceso que está usando obj continuará ejecutándose.

Esto creará problemas extraños para usted ya que el estado obj's puede cambiarse mientras que el otro hilo lo está usando (todo depende de cómo se implemente el método Dispose). Huelga decir que esta aplicación de IDisposable, subprocesamiento y la declaración using será problemático en el mejor de los casos.

1

Cuando se sale del bloque de uso en el hilo principal, .Dispondrá() el objeto, lo que podría causar todo tipo de divertidos problemas de concurrencia. Sin embargo, el objeto no se recogerá como basura: se mantendrá, pero en un estado no válido, dependiendo de su implementación de .Dispose().

11

Pasarán cosas interesantes.

Específicamente, se llamará al método de eliminación en SomeObject, antes o después de que se haya llamado al trabajo, ya que puede o no haberse programado para ejecutarse en ese punto.

Después de eso, depende de lo que haga el método de eliminación de SomeObject; si, por ejemplo, publica una conexión Sql que no se usa en "Trabajo", entonces no debería haber un problema; si, sin embargo, SomeObject espera que no se haya eliminado, es probable que tengas una excepción en ese hilo.

+0

Cosas interesantes, buena. – Groo

+0

Por alguna razón, me hace pensar en Mos Def en The Italian Job: "Tuve una mala experiencia". –

2

El objeto llamará a Dispose al final del bloque. Continuará funcionando, pero obj se volverá inestable ya que Dispose se supone que cerrará las conexiones, etc. Ahora es posible que obj esté configurado para verificar si algo está en uso y cerrarlo después, pero no contaría con esto a menos que usted ha escrito el objeto para manejar esto.

Cuestiones relacionadas