2009-03-29 15 views
5

tengo el siguiente código:datos que pasan en un método de devolución de llamada (a través de BeginInvoke) en C#

delegate int doStuffDel(int instanceNo, int sleepTime, int repeatCount); 
    string result; 

    private int doStuff(int instanceNo, int sleepTime, int repeatCount) 
    { 
     for (int i = 0; i < repeatCount; i++) 
     { 
      Console.Write(instanceNo); 
      Thread.Sleep(sleepTime); 
     } 
     result = instanceNo + " repeated " + repeatCount; 
     return instanceNo; 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     doStuffDel del = doStuff; 
     IAsyncResult ar = del.BeginInvoke(3, 120, 50, finishedCallback, result); 
    } 

    private void finishedCallback(IAsyncResult ar) 
    { 
     Console.WriteLine("Done. The result was " + ar.AsyncState.ToString()); 
    } 

me pareció que el res.AsyncState devolvería la cadena, aprobada como último argumento en la llamada a BeginInvoke, pero es nulo. ¿Alguien sabe por qué?

PD, sé que podría pasar el del como último argumento en BeginInvoke y luego llamar a EndInvoke en la devolución de llamada, para obtener algún resultado del método doStuff, - ¡o podría obtener el valor val de la clase! - pero me sorprende que el AsyncState en el objeto AsyncResult sea nulo ...

+1

Llama siempre a EndInvoke en un IAsyncResult; de lo contrario, podrías estar perdiendo recursos no administrados (eventos). –

Respuesta

8

El valor de ar.AsyncState es el valor del resultado cuando originalmente lo pasa al BeginInvoke. El hecho de que cuando lo pasó, utilizó el valor de result no significa que esté "vinculado" a la variable de resultado. Es solo el valor de la variable result cuando lo pasa para comenzar.

Para ver esto, establezca result en algún valor de prueba antes de llamar al BeginInvoke, o simplemente pase un literal de cadena en su lugar. De cualquier manera, obtendrá ese valor en la devolución de llamada.

Por otro lado, su devolución de llamada y su delegado original tienen el mismo objeto de destino, por lo que podría usar result dentro de la devolución de llamada y tendría el valor que desea; esa es otra forma de mantener el estado.

1

Se transfiere cuando llama a BeginInvoke. En ese momento, resultado es nulo. Si establece resultado antes de la llamada, lo verá en la devolución de llamada.

1

El problema es que se pasa el valor de result - lo que (antes de doStuff) es null. Las actualizaciones a result dentro de doStuff no afectan el estado asincrónico.

Cuestiones relacionadas