У меня есть метод, реализованный с использованием шаблона Асинхронного метода на основе событий . Я также хочу предложить синхронную версию этого метода, но не хочу переписывать его (поскольку метод включает в себя вызов WCF из Silverlight, версия Async должна быть основным методом).
Я предложил следующий универсальный метод для преобразования асинхронного вызова на основе событий в синхронный:
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;
}
Итак, если у меня есть этот асинхронный метод:
void ConnectAsync(string address,
string userName,
string password,
EventHandler<ConnectCompletedEventArgs> completionCallback)
Я могу преобразовать его в синхронный вызов, например:
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;
}
}
Меня беспокоит использование переменной eventArgs, которая фиксируется в замыкании. Он устанавливается в одном потоке и доступен из другого. Достаточно ли моего использования ManualResetEvent, чтобы гарантировать правильное считывание значения после сигнализации о событии, или мне нужно сделать что-то еще?
Ну, вы на этом, вы можете прокомментировать обработку исключений здесь. Мой план состоит в том, что метод Async обернет исключения, возникающие ниже в стеке, в ConnectionException, или что-то в этом роде, поэтому я думаю, что перебрасывание исключения является правильным в этом случае.