Ich weiß, dass dies eine alte Frage ist, aber ich möchte ein Beispiel dafür anbieten, wie das Yield-Schlüsselwort kreativ verwendet werden kann. Ich habe wirklich von dieser Technik profitiert. Hoffentlich hilft dies allen anderen, die über diese Frage stolpern.
Hinweis: Stellen Sie sich das Yield-Schlüsselwort nicht nur als eine andere Möglichkeit zum Erstellen einer Sammlung vor. Ein großer Teil der Ertragskraft besteht darin, dass die Ausführung in Ihrer Methode oder Eigenschaft angehalten wird, bis der aufrufende Code über den nächsten Wert iteriert. Hier ist mein Beispiel:
Die Verwendung des Yield-Schlüsselworts (neben Rob Eisenburgs Implementierung von Caliburn.Micro Coroutines ) 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();
}
Dadurch wird mein BusyIndicator aktiviert, die Anmeldemethode in meinem Webdienst aufgerufen, mein IsLoggedIn-Flag auf den Rückgabewert gesetzt und dann der BusyIndicator wieder deaktiviert.
So funktioniert das: IResult verfügt über eine Execute-Methode und ein Completed-Ereignis. Caliburn.Micro greift den IEnumerator aus dem Aufruf von HandleButtonClick () ab 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 in HandleButtonClick () angehalten, und BeginExecute () fügt dem Ereignis Completed einen Ereignishandler hinzu und ruft Execute () auf. IResult.Execute () kann entweder eine synchrone oder eine asynchrone Aufgabe ausführen und löst das Ereignis "Abgeschlossen" aus, wenn es abgeschlossen ist.
LoginResult sieht ungefähr 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 zu durchlaufen, um zu beobachten, was los ist.
Hoffe das hilft jemandem! Ich habe es wirklich genossen, die verschiedenen Verwendungsmöglichkeiten von Erträgen zu erkunden.
yield
ist gebundenIEnumerable<T>
und seine Art. Es ist in einer irgendwie faulen Bewertung