2009-03-29 6 views
5

Mam następujący kod:Przekazywanie danych do metody wywołania zwrotnego (za pośrednictwem BeginInvoke) w 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()); 
    } 

Myślałem, że res.AsyncState zwróci ciąg, przekazany jako ostatni argument w wywołaniu BeginInvoke, ale jest zerowy. Czy ktoś wie dlaczego?

PS, Wiem, że mogłem przekazać del jako ostatni argument w BeginInvoke, a następnie wywołać EndInvoke w wywołaniu zwrotnym, aby uzyskać wynik z metody doStuff, - lub mógłbym uzyskać ciąg znaków val z klasy! - ale jestem zaskoczony, że AsyncState na obiekcie AsyncResult jest pusty ...

+1

Zawsze wywołuj EndInvoke na IAsyncResult, w przeciwnym razie możesz przeciekać niezarządzane zasoby (zdarzenia). –

Odpowiedz

8

Wartość ar.AsyncState jest wartością wyniku, gdy pierwotnie przekazano go do BeginInvoke. Fakt, że po jej minięciu użyłeś wartości result, nie oznacza, że ​​jest "związana" ze zmienną wyniku. Jest to po prostu wartość zmiennej result po jej przejściu.

Aby to zobaczyć, ustaw result na pewną wartość testową przed wywołaniem BeginInvoke lub po prostu podaj literał ciągu zamiast tego. Tak czy inaczej, otrzymasz tę wartość w wywołaniu zwrotnym. Z drugiej strony, twój oddzwonienie i oryginalny delegat mają ten sam obiekt docelowy, więc możesz użyć funkcji result w ramach wywołania zwrotnego i miałby on wartość, którą chcesz - to inny sposób na utrzymanie stanu.

1

Jest przekazywany, gdy wywołasz BeginInvoke. W tym czasie wynik ma wartość null. Jeśli przed połączeniem ustawisz wynik, zobaczysz go w wywołaniu zwrotnym.

1

Problemem jest to, że można przejść wartość z result- co (przed doStuff) jest null. Aktualizacje result w ramach doStuff nie wpływają na stan asynchroniczny.

Powiązane problemy