Ich habe eine Methode implementiert mit der Event-based Asynchronous method pattern. Ich möchte auch eine synchrone Version dieser Methode anbieten, möchte sie aber nicht neu schreiben (da die Methode einen Aufruf von Silverlight an WCF erfordert, muss die Async-Version die primäre Methode sein).Ist diese Methode zum Konvertieren einer asynchronen Methode in eine synchrone Methode richtig?
Ich habe mit dem folgenden allgemeinen Verfahren kommen ein ereignisbasierte asynchrone Aufruf an einen Synchron ein konvertieren:
Func<TArg1, TArg2, TArg3, TEventArgs>
CreateSynchronousMethodFromAsync<TArg1, TArg2, TArg3, TEventArgs>(
Action<TArg1, TArg2, TArg3, EventHandler<TEventArgs>> asyncMethod)
where TEventArgs : AsyncCompletedEventArgs
{
Func<TArg1, TArg2, TArg3, TEventArgs> syncMethod = (arg1, arg2, arg3) =>
{
TEventArgs eventArgs = null;
using (var waitHandle = new ManualResetEvent(false))
{
asyncMethod(arg1, arg2, arg3, (sender, e) =>
{
eventArgs = e;
waitHandle.Set();
});
waitHandle.WaitOne();
return eventArgs;
}
};
return syncMethod;
}
Also, wenn ich diese asynchrone Methode:
void ConnectAsync(string address,
string userName,
string password,
EventHandler<ConnectCompletedEventArgs> completionCallback)
I kann es in einen synchronen Anruf wie folgt umwandeln:
public void Connect(string address, string userName, string password)
{
Func<string, string, string, ConnectCompletedEventArgs> connect =
CreateSynchronousMethodFromAsync<string, string, string, ConnectCompletedEventArgs>(ConnectAsync);
var connectResult = connect(address, userName, password);
if (connectResult.Error != null)
{
throw connectResult.Error;
}
}
Mein Anliegen ist über die uns e der eventArgs-Variable, die in der Schließung erfasst wird. Es wird in einem Thread festgelegt und von einem anderen abgerufen. Ist die Verwendung von ManualResetEvent ausreichend, um ein korrektes Lesen des Werts nach der Signalisierung des Ereignisses zu garantieren, oder muss ich etwas anderes tun?
Nun, Sie sind dabei, vielleicht möchten Sie hier einen Kommentar zum Umgang mit Ausnahmen abgeben. Mein Plan ist, dass die Async-Methode eine Ausnahmen, die unten in einer ConnectionException auftreten, umschlingt, oder etwas in der Art, so dass ich denke, dass das Auslösen der Ausnahme in diesem Fall korrekt ist.
Mein Code ist nur für die Verwendung mit Methoden vorgesehen, die dem Pattern Eventbased Asynchronous method entsprechen. Meine innere Methode BeginConnect, deren Implementierung ich nicht gezeigt habe, kümmert sich darum, die Begin/End-Aufrufe zu beenden. –
Beachten Sie, dass Sie lieber als "throw connectionResult.Error" das als eine innere Ausnahme in eine neue Ausnahme umbrechen möchten, damit die Stapelüberwachung der ursprünglichen Ausnahme beibehalten wird. – jerryjvl
@Sam: Ich würde empfehlen, die Methode basierend auf der Konvention in dem verknüpften Artikel zu benennen, um Verwirrung zu vermeiden ... machen Sie stattdessen 'ConnectAsync'. – jerryjvl