Instrucción de uso y try-catch()-por último, la repetición?

El uso de(…) la instrucción es azúcar sintáctico para try{} finally {}.

Pero si luego tengo una instrucción como la siguiente:

using (FileStream fs = File.Open(path))
{


}

Ahora quiero atrapar las excepciones que la apertura de este archivo puede producir (y esto es bastante alto riesgo de código en que puede fallar debido a que el medio ambiente), pero si escribo try-catch en el interior de no ser la repetición? Cuando el código se compila a la IL, supongo que la repetición se borran cuando el código es JITted?

Sin embargo, me gustaría atrapar las excepciones de la apertura de un archivo puede causar (por lo que debe envolver el try-catch fuera de la instrucción del ámbito de aplicación), y también las excepciones por lo que hago dentro de el uso de bloque, por lo que debo añadir el try-catch en el interior del bloque.

Parece que voy a añadir un montón de repetición de lo que el CLR probablemente no en el interior. ¿El CLR agregar cláusulas catch?

Mi colega argumentó que una instrucción es complicado (pero esto fue debido a que una sola línea fue un poco largo debido a que me duro la codificación de ellos como yo lo necesitaba cambiar muy rápidamente y no tienen acceso a otras partes de la base de código). Dijo el colega no utilizar la instrucción, pero ¿hay alguna diferencia funcional entre la instrucción y try-finally/try-catch-finally? Me hizo ver un caso de este, donde los servicios WCF tiene un no bien conocida esquina de caso sobre el uso de finalmente y devolución de valores (algo acerca por fin). La solución fue utilizar un bloqueo de verificación. No hay nada como esto en C#?

En otra nota, son todos los tipos que implementan IDisposale los propietarios de los recursos no administrados? Una discusión con mi amigo señaló que la respuesta a ser que no. (También he leído algunos hilos en la sección de este foro, algunos muy buenos conocimientos).

OriginalEl autor GurdeepS | 2009-09-02

5 Kommentare

  1. 7

    Puede implementar el patrón de sí mismo si usted necesita para manejar algunas excepciones si usted realmente desea. Personalmente, me resulta más sencillo (y lo que es más importante, claro) simplemente envuelva el uso de bloques try/catch.

    Pero si lo hace usted mismo, asegúrese de que usted consigue la derecha. El Using bloque también crea un anónimo alcance de bloque para que la variable se convierte en elegible para la colección de antes. El .Dispose() método que se llama al final de la Using bloque sólo se limpia no administrado recursos, por lo que cualquier memoria de su objeto contiene puede colgar alrededor de un poco más de tiempo. No es probable que una gran preocupación, pero vale la pena recordar que sólo en caso de.

    Entonces, para hacer una adaptación directa del patrón, el código necesita para parecerse más al este:

    {
        FileStream fs;
        try
        {
            fs = File.Open(path);
    
        }
        catch (FileNotFoundException e) { /* ... */ }
        catch (IOException e) { /* ... */ }
        catch (Exception e) {/* ... */}
        finally
        {
            if (fs != null) fs.Dispose();
        }
    }

    Personalmente, me gustaría ver Using ampliado para apoyar Catch y Finally bloques. Puesto que ya estamos realizando una transformación en el código, que no parece que esto habría que agregar que mucho complejidad adicional.

    El uso que hace de soporte por último, aunque? Donde averiguaste sobre el uso, el uso de un anónimo alcance de bloque? Me gustaría saber más acerca de esto. Así que cuando abro un archivo en un bloque using (por ejemplo, FileSream.Open()), esta excepción se propague. Si la instrucción de uso de implementos de try/finally, que tengo que acabar que en try/catch sólo para tener la captura.

    OriginalEl autor Joel Coehoorn

  2. 7

    Mi preferencia sería la de mantener la instrucción de uso y se envuelve en un try/catch. El exterior try/catch captura con independencia de las excepciones que usted necesita para ver, mientras se ignora el Dispose(). Esto tiene la ventaja adicional de proteger de ti mismo debe refactorizar esto más adelante para mover el try/catch en otros lugares (como en una función de llamada).

    En cuanto a tu pregunta acerca de IDisposable: cualquier persona puede hacer esto para cualquier razón que les gusta. No hay ninguna razón técnica para que se limite a los recursos no administrados. (Si o no debe ser limitado a los recursos no administrados en su código es otra cuestión).

    OriginalEl autor Jon B

  3. 4

    La mayor diferencia entre el uso y try-finally es que con sólo llamar a la Dispose() método. En el caso de implementar su propio bloque finally se puede hacer otra lógica, por ejemplo el registro, que no se incluyó en el uso.

    +1 por falta

    OriginalEl autor David Basarab

  4. 4

    Si usted necesita para gestionar de forma explícita los diferentes casos excepcionales que puedan ocurrir durante la instrucción, podría reemplazar using con try/catch/finally y llame a Dispose() explícitamente en el último. O usted podría poner un try/catch alrededor de la using bloque para separar las circunstancias excepcionales de asegurar su eliminación.

    La sólo cosa using hace es garantizar Dispose() es llamada, incluso si se produce una excepción en el bloque. Que es un muy limitado, muy específica de la aplicación de la general try/[catch]/finally estructura.

    Lo importante es que ninguna de estas opciones tiene ningún impacto real – siempre que no lo necesita, es legible y comprensible, a quién le importa? No es como un extra a tratar va a ser un cuello de botella o algo!

    Para responder a su última pregunta – no, IDisposable definitivamente no necesariamente significa que el ejecutor tiene asas para recursos no administrados. Es mucho más sencillo y más genérico patrón que eso. He aquí un ejemplo útil:

    public class Timer : IDisposable
    {
        internal Stopwatch _stopwatch;
        public Timer()
        {
            this._stopwatch = new Stopwatch();
            this._stopwatch.Start();
        }
    
        public void Dispose()
        {
            this._stopwatch.Stop();
        }
    }

    Podemos utilizar este tiempo de cosas sin tener que explícitamente se basan en inicio y dejar de ser llamados por el uso de:

    using(Timer timer = new Timer())
    {
        //do stuff
    }

    OriginalEl autor Rex M

  5. 3

    La using construir es una abreviatura de una try/finally bloque. Es decir, el compilador genera:

    FileStream fs = null;
    try
    {
        fs = File.Open(path);
        //...
    }
    finally
    {
        if (fs != null)
            fs.Dispose();
    }

    Por lo que es adecuado para uso using si usted no necesita un catch, pero si lo hace, entonces usted debe utilizar un normal try/catch/finally.

    No hay nada malo con envoltura using sí mismo en try/catch. Es más clara que la de finally porque es inmediatamente obvio lo que los recursos son liberados después de que el bloque de salidas sin tener que mirar finally.

    OriginalEl autor AndyM

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea