es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Retorno de rendimiento de cortocircuito y limpieza/desecho.

Toma este ejemplo pseudo código:

    static System.Runtime.InteropServices.ComTypes.IEnumString GetUnmanagedObject() => null;
    static IEnumerable<string> ProduceStrings()
    {
        System.Runtime.InteropServices.ComTypes.IEnumString obj = GetUnmanagedObject();
        var result = new string[1];
        var pFetched = Marshal.AllocHGlobal(sizeof(int));
        while(obj.Next(1, result, pFetched) == 0)
        {
            yield return result[0];
        }
        Marshal.ReleaseComObject(obj);
    }

    static void Consumer()
    {
        foreach (var item in ProduceStrings())
        {
            if (item.StartsWith("foo"))
                return;
        }
    }

La pregunta es, si decido no enumerar todos los valores, ¿cómo puedo informar al productor que realice la limpieza?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para informar al productor que realice una limpieza cuando no se enumeran todos los valores, se puede utilizar un bloque try-finally dentro del método ProduceStrings. El bloque finally se asegurará de que el objeto no administrado se libere independientemente de si se enumeraron todos los valores o no. Aquí hay un ejemplo de implementación:

    static IEnumerable<string> ProduceStrings()
    {
        System.Runtime.InteropServices.ComTypes.IEnumString obj = GetUnmanagedObject();
        var result = new string[1];
        var pFetched = Marshal.AllocHGlobal(sizeof(int));
        try
        {
            while(obj.Next(1, result, pFetched) == 0)
            {
                yield return result[0];
            }
        }
        finally
        {
            Marshal.ReleaseComObject(obj);
        }
    }
    

    Con esta implementación, si el método Consumer decide no enumerar todos los valores, el bloque finally dentro del método ProduceStrings aún se ejecutará, liberando el objeto no administrado.

Comments are closed.