Frage Schreibe eine Async-Methode, die auf einen Bool wartet


Ich würde gerne eine Methode schreiben, die das wird await wenn eine Variable auf "True" gesetzt werden soll.

Hier ist der Psudo-Code.

bool IsSomethingLoading = false
SomeData TheData;

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

TheData wird von einem Prism Event zusammen mit dem IsSomethingLoading Variable.

Ich habe einen Anruf bei der GetTheData Methode, aber ich möchte, dass es async läuft (im Moment gibt es nur Null zurück, wenn die Daten nicht bereit sind. (Das führt zu anderen Problemen.)

Gibt es eine Möglichkeit, dies zu tun?


12
2018-02-27 21:38


Ursprung


Antworten:


In vielen Situationen wie diesem, was Sie brauchen, ist ein TaskCompletionSource.

Sie verfügen wahrscheinlich über eine Methode, mit der die Daten zu einem bestimmten Zeitpunkt generiert werden können, sie wird jedoch nicht mit einer Aufgabe ausgeführt. Vielleicht gibt es eine Methode, die einen Callback verwendet, der das Ergebnis liefert, oder ein Ereignis, das ausgelöst wird, um anzuzeigen, dass ein Ergebnis vorliegt, oder einfach einen Code, der a verwendet Thread oder ThreadPool dass Sie nicht dazu neigen, in die Nutzung zu re-Faktorisieren Task.Run.

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 benötigen / wollen, bieten TaskCompletionSource für den Arbeiter, oder eine andere Klasse, oder auf andere Weise, es einem größeren Umfang aussetzen, ich habe festgestellt, dass es oft nicht benötigt wird, obwohl es eine sehr mächtige Option ist, wenn es angemessen ist.

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


13
2018-02-27 21:47



Du könntest einen benutzen TaskCompletionSource als dein Signal und await Das:

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

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

Und in Ihrem Prism-Ereignis tun Sie:

IsSomethingLoading.SetResult(true);

9
2018-02-27 21:48