2013-02-27 3 views
12

Ich möchte eine Methode schreiben, die await für eine Variable auf True festgelegt wird.Schreiben Sie eine Async-Methode, die auf einen bool wartet

Hier ist der Psudo-Code.

bool IsSomethingLoading = false 
SomeData TheData; 

public async Task<SomeData> GetTheData() 
{ 
    await IsSomethingLoading == true; 
    return TheData; 
} 

TheData wird zusammen mit dem IsSomethingLoading Variable durch ein Prisma Ereignis eingestellt werden.

Ich habe einen Aufruf an die GetTheData Methode, aber ich möchte es async (jetzt laufen sie wieder nur null, wenn die Daten nicht bereit ist. (Das führt zu anderen Problemen.)

Gibt es eine Art und Weise, dies zu tun?

+1

Warum nicht eine Warte Griff benutzen? – Xaqron

+0

es fühlt sich an, als würde hier etwas fehlen .. sollte nicht das 'erwarten IsSomethingLoading == true' eher warten' warten InitiateLoading(); '? – Default

+0

@EricLippert - Ich denke, ich möchte eine asynchrone warten. (Aber ich bin mir nicht sicher.) Meine Anrufmethode wird eine Warteanzeige auf einem Teil des Bildschirms setzen. Wenn der Anrufer zurückkehrt, wird die Warteanzeige entfernt. Aber ich brauche die Benutzeroberfläche, die während der Zeit, die die Warteanzeige anzeigt, reagiert. Der "Callback" -Stil von Async/Await scheint dies zu bieten ... – Vaccano

Antwort

13

in vielen Situationen wie das, was Sie brauchen, ist ein TaskCompletionSource.

Sie haben wahrscheinlich eine Methode, um die Daten zu einem bestimmten Zeitpunkt zu erzeugen, ist in der Lage, es gibt aber keine verwenden Aufgabe, es zu tun.Vielleicht gibt es eine Methode, die einen Rückruf nimmt, der das Ergebnis liefert, oder ein Ereignis, das indi ausgelöst wird Geben Sie an, dass ein Ergebnis vorliegt, oder codieren Sie einfach mit einer Thread oder ThreadPool, dass Sie nicht dazu neigen, die Verwendung von Task.Run neu zu berücksichtigen.

public Task<SomeData> GetTheData() 
{ 
    TaskCompletionSource<SomeData> tcs = new TaskCompletionSource<SomeData>(); 
    SomeObject worker = new SomeObject(); 
    worker.WorkCompleted += result => tcs.SetResult(result); 
    worker.DoWork(); 
    return tcs.Task; 
} 

Während Sie brauchen/will die TaskCompletionSource den Arbeiter zur Verfügung zu stellen oder eine andere Klasse oder in irgendeiner anderen Weise aussetzen zu einem breiteren Umfang habe ich es oft nicht nötig gefunden, obwohl es eine sehr mächtige Option, wenn es angemessen ist.

Es ist auch möglich, dass Sie Task.FromAsync verwenden können, um eine Aufgabe basierend auf einer asynchronen Operation zu erstellen, und dann diese Aufgabe entweder direkt oder await in Ihrem Code zurückgeben.

9

Sie könnten ein TaskCompletionSource als Signal verwenden und await dass:

TaskCompletionSource<bool> IsSomethingLoading = new TaskCompletionSource<bool>(); 
SomeData TheData; 

public async Task<SomeData> GetTheData() 
{ 
    await IsSomethingLoading.Task; 
    return TheData; 
} 

Und in Ihrem Prism Fall tun:

IsSomethingLoading.SetResult(true); 
+1

Warum ist ein 'TCS ' und nicht ein 'TCS ' direkt? – Servy