2016-06-22 5 views
-1

Ich habe ein Ereignis auf einem Usercontrol (winform), die ich höre:Async Anruf auf GUI-Ereignisse

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = ?await? _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

_businessObject.AsyncCall() hat die folgende Signatur:

public async Task<SomeResult> AsyncCall(); 

Wie kann ich das nennen async Verfahren während:

  1. blockiert nicht das GUI-Thread
  2. sein in der Lage, die ApplySomethingOnTheGuiBasedOnTheResult nach meiner asynchronen Methode aufgerufen wurde
  3. In der Lage, die ApplySomethingOnTheGuiBasedOnTheResult in der richtigen (GUI) -Thread aufrufen.

Was ich versucht:

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = await _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

-> Ist nicht kompilieren, da meine Event-Handler nicht async ist.

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = _businessObject.AsyncCall().Result; 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

-> Die Anwendung

public void OnSomething(SomeEventArgs args){ 
    _businessObject.AsyncCall().ContinueWith(t=>{ 
     if(InvokeRequired){ 
      Invoke(new Action(()=>ApplySomethingOnTheGuiBasedOnTheResult(t.Result))); 
     } 
    }); 
} 

einfrieren -> funktioniert, aber ich war Hopping dass es ein schöner Weg, um es mit dem Asynchron/await zu tun war.

Antwort

2

Sie müssen lediglich Ihre Handler als async markieren:

public async void OnSomething(SomeEventArgs args) 
{ 
    SomeResult result = await _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

Ich weiß es nicht asyc mit Rückgabetyp void zu verwenden, wird empfohlen, (normalerweise sollte es Task oder Task<sometype> sein), aber wenn der Fall, dass Signatur erfordert , es ist der einzige Weg.

Auf diese Weise wird der Kontrollfluss an den Aufrufer unter der await Anweisung zurückgegeben. Wenn die AsyncCall beendet ist, wird die Ausführung schließlich wieder aufgenommen nach der await auf dem UI-Thread.

+2

Ich möchte nur die OP und zukünftige Leser betonen, der einzige Ort, den Sie jemals 'async void' schreiben sollten, ist, wenn Sie einen Event-Handler wie folgt machen. Wenn Sie nicht einen Event-Handler schreiben, sollten Sie 'async Task' machen –

+0

@ScottChamberlain richtig, ich habe hinzugefügt, während Sie kommentiert. –

+0

Kein Problem, ich habe dir schon +1 ohne Edit gegeben :) –