我正在爲客戶端/服務器應用程序中的「客戶端」類實現異步命令模式。我在過去做過一些套接字編碼,我喜歡它們在Socket/SocketAsyncEventArgs類中使用的新異步模式。異步命令模式 - 異常處理
我的異步方法如下所示:public bool ExecuteAsync(Command cmd);
如果執行處於掛起狀態,則返回true;如果同步完成,則返回false。 我的問題是:即使發生異常,我是否應該始終調用回調函數(cmd.OnCompleted)?還是應該從ExecuteAsync引發異常?
這裏有一些更多的細節,如果你需要它們。這與使用SocketAsyncEventArgs類似,但我們的類名爲SomeCmd,而不是SocketAsyncEventArgs。
SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
this.ConnectionToServer.ExecuteAsync(cmd);
與Socket類,如果你需要與你的回調方法(在這種情況下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