Я реализую асинхронный командный шаблон для класса «клиент» в приложении клиент/сервер. В прошлом я сделал некоторую кодировку сокетов, и мне нравится новый шаблон Async, который они использовали в классах Socket/SocketAsyncEventArgs.Шаблон команды Async - обработка исключений
Мой метод async выглядит следующим образом: public bool ExecuteAsync(Command cmd);
Возвращает true, если выполнение выполняется в ожидании и false, если оно выполнено синхронно. Мой вопрос: должен ли я всегда вызывать обратный вызов (cmd.OnCompleted) даже в случае исключения? Или я должен исключать исключения из ExecuteAsync?
Вот еще несколько деталей, если они вам понадобятся. Это похоже на использование SocketAsyncEventArgs, но вместо SocketAsyncEventArgs мой класс называется SomeCmd.
SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
this.ConnectionToServer.ExecuteAsync(cmd);
Как с классом сокета, если вам необходимо согласовать с вашим методом обратного вызова (SomeCmd_OnCompleted в данном случае), вы можете использовать возвращаемое значение ExecuteAsync знать, если операция находится на рассмотрении (истина) или если операция выполнена синхронно.
SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
if(this.ConnectionToServer.ExecuteAsync(cmd))
{
Monitor.Wait(this.WillBePulsedBy_SomeCmd_OnCompleted);
}
Вот сильно упрощенная версия моих базовых классов, но вы можете увидеть, как это работает:
class Connection
{
public bool ExecuteAsync(Command cmd)
{
/// CONSIDER: If you don't catch every exception here
/// then every caller of this method must have 2 sets of
/// exception handling:
/// One in the handler of Command.OnCompleted and one where ExecuteAsync
/// is called.
try
{
/// Some possible exceptions here:
/// 1) remote is disposed. happens when the other side disconnects (WCF).
/// 2) I do something wrong in TrackCommand (a bug that I want to fix!)
this.TrackCommand(cmd);
remote.ServerExecuteAsync(cmd.GetRequest());
return true;
}
catch(Exception ex)
{
/// Command completing synchronously.
cmd.Completed(ex, true);
return false;
}
}
/// <summary>This is what gets called by some magic when the server returns a response.</summary>
internal CommandExecuteReturn(CommandResponse response)
{
Command cmd = this.GetTrackedCommand(response.RequestId);
/// Command completing asynchronously.
cmd.Completed(response, false);
}
private IServer remote;
}
abstract class Command: EventArgs
{
internal void Completed(Exception ex, bool synchronously)
{
this.Exception = ex;
this.CompletedSynchronously = synchronously;
if(this.OnCompleted != null)
{
this.OnCompleted(this);
}
}
internal void Completed(CommandResponse response, bool synchronously)
{
this.Response = response;
this.Completed(response.ExceptionFromServer, synchronously)
}
public bool CompletedSynchronously{ get; private set; }
public event EventHandler<Command> OnCompleted;
public Exception Exception{ get; private set; }
internal protected abstract CommandRequest GetRequest();
}
Теперь, почему Я не думаю об этом? Самое смешное, что я на самом деле сделал это раньше для класса, который запускает ряд запросов. – 2008-11-18 03:15:02