Ich weiß, dass dies eine alte Frage ist, aber ich möchte ein Beispiel dafür geben, wie das Schlüsselwort yield kreativ eingesetzt werden kann. Ich habe vraiment von dieser Technik profitiert. Ich hoffe, dass dies für alle anderen, die über diese Frage stolpern, eine Hilfe ist.
Hinweis: Betrachten Sie das Schlüsselwort yield nicht nur als eine weitere Möglichkeit, eine Sammlung aufzubauen. Ein großer Teil der Macht von yield liegt in der Tatsache, dass die Ausführung pausiert in Ihrem Methode oder Eigenschaft, bis der aufrufende Code über den nächsten Wert iteriert. Hier ist mein Beispiel:
Die Verwendung des Schlüsselworts yield (zusammen mit Rob Eisenburgs Caliburn.Micro-Koroutinen Implementierung) ermöglicht es mir, einen asynchronen Aufruf an einen Webdienst wie diesen auszudrücken:
public IEnumerable<IResult> HandleButtonClick() {
yield return Show.Busy();
var loginCall = new LoginResult(wsClient, Username, Password);
yield return loginCall;
this.IsLoggedIn = loginCall.Success;
yield return Show.NotBusy();
}
Dies schaltet meinen BusyIndicator ein, ruft die Login-Methode meines Webdienstes auf, setzt mein IsLoggedIn-Flag auf den Rückgabewert und schaltet den BusyIndicator dann wieder aus.
Das funktioniert folgendermaßen: IResult hat eine Execute-Methode und ein Completed-Ereignis. Caliburn.Micro greift sich den IEnumerator aus dem Aufruf von HandleButtonClick() und übergibt ihn an eine Coroutine.BeginExecute-Methode. Die BeginExecute-Methode beginnt mit der Iteration durch die IResults. Wenn das erste IResult zurückgegeben wird, wird die Ausführung innerhalb von HandleButtonClick() angehalten, und BeginExecute() hängt einen Ereignishandler an das Ereignis Completed an und ruft Execute() auf. IResult.Execute() kann entweder eine synchrone oder eine asynchrone Aufgabe ausführen und feuert das Ereignis Completed ab, wenn es fertig ist.
LoginResult sieht in etwa so aus:
public LoginResult : IResult {
// Constructor to set private members...
public void Execute(ActionExecutionContext context) {
wsClient.LoginCompleted += (sender, e) => {
this.Success = e.Result;
Completed(this, new ResultCompletionEventArgs());
};
wsClient.Login(username, password);
}
public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
public bool Success { get; private set; }
}
Es kann hilfreich sein, so etwas einzurichten und die Ausführung Schritt für Schritt zu beobachten.
Ich hoffe, das hilft jemandem weiter! Es hat mir wirklich Spaß gemacht, die verschiedenen Verwendungsmöglichkeiten von Rendite zu erforschen.