异步命令模式 - 异常处理 [英] Async command pattern - exception handling

查看:159
本文介绍了异步命令模式 - 异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现的客户类中的客户机/服务器应用程序的异步命令模式。我做了一些插座编码在过去,我喜欢他们在插座使用了新的异步模式/的SocketAsyncEventArgs类。

我的异步方法是这样的:公共BOOL ExecuteAsync(CMD命令); 如果执行挂起和虚假如果同步完成返回TRUE。 我的问题是:我应该始终调用回调函数(cmd.OnCompleted),即使是在异常的情况?或者我应该扔直接从ExecuteAsync例外?

下面是一些更多的细节,如果你需要他们。这是类似于使用的SocketAsyncEventArgs,但不是让SocketAsyncEventArgs我的类被称为SomeCmd。

  SomeCmd CMD =新SomeCmd(23,14,10,加息!);
cmd.OnCompleted + = this.SomeCmd_OnCompleted;
this.ConnectionToServer.ExecuteAsync(CMD);
 

与Socket类,如果你需要与你的回调方法(SomeCmd_OnCompleted在这种情况下)协调,则可以使用ExecuteAsync的返回值知道操作正在等待(真),如果操作同步完成。

  SomeCmd CMD =新SomeCmd(23,14,10,加息!);
cmd.OnCompleted + = this.SomeCmd_OnCompleted;
如果(this.ConnectionToServer.ExecuteAsync(CMD))
{
    Monitor.Wait(this.WillBePulsedBy_SomeCmd_OnCompleted);
}
 

下面是我的基类的大大简化版本,但你可以看到它是如何工作的:

 类连接
{
    公共BOOL ExecuteAsync(命令CMD)
    {
    ///考虑:如果你没有在这里抓住每一个异常
    ///那么这种方法的每一个调用方必须具有2套
                ///异常处理:
    ///一个在Command.OnCompleted的处理程序和一个在那里ExecuteAsync
    ///被调用。
    	尝试
    {
    这里///一些可能的例外情况:
    /// 1)远程设置。发生在另一侧断开(WCF)。
    /// 2)我做错事的TrackCommand(我要修复一个bug!)
    this.TrackCommand(CMD);
    remote.ServerExecuteAsync(cmd.GetRequest());
    返回true;
    }
    赶上(例外前)
    {
    ///命令完成同步。
    cmd.Completed(恩,真正的);
    返回false;
    }
    }
    ///<总结>这是被调用一些魔法时,服务器返回响应< /总结>
    内部CommandExecuteReturn(CommandResponse响应)
    {
    指令CMD = this.GetTrackedCommand(response.RequestId);
    ///命令完成异步。
    cmd.Completed(响应,假);
    }

    私人iServer的遥控器;
}

抽象类命令:EventArgs的
{
    内部空隙完成(异常前,布尔同步)
    {
    this.Exception =前;

    this.CompletedSynchronously =同步;

    如果(this.OnCompleted!= NULL)
    {
    this.OnCompleted(本);
    }
    }

    内部空隙完成(CommandResponse响应,布尔同步)
    {
    this.Response =响应;
    this.Completed(response.ExceptionFromServer,同步)
    }

    公共BOOL CompletedSynchronously {获得;私定; }

    公共事件的EventHandler<指挥与GT; OnCompleted;

    公共异常异常{获得;私定; }

    内部保护的抽象CommandRequest的GetRequest();
}
 

解决方案

从调度点抛出异常可能会或可能不会有用

调用回调传递一个异常参数要求完成回调做2个不同的事情

第二个回调异常报告可能是有意义的,而不是

I am implementing an asynchronous command pattern for the "client" class in a client/server application. I have done some socket coding in the past and I like the new Async pattern that they used in the Socket / SocketAsyncEventArgs classes.

My async method looks like this: public bool ExecuteAsync(Command cmd); It returns true if the execution is pending and false if it completed synchronously. My question is: Should I always call the callback (cmd.OnCompleted), even in the event of an exception? Or should I throw exceptions right from ExecuteAsync?

Here are some more details if you need them. This is similar to using SocketAsyncEventArgs, but instead of SocketAsyncEventArgs my class is called SomeCmd.

SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
this.ConnectionToServer.ExecuteAsync(cmd);

As with the Socket class, if you need to coordinate with your callback method (SomeCmd_OnCompleted in this case), you can use the return value of ExecuteAsync to know if the operation is pending (true) or if the operation completed synchronously.

SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
if( this.ConnectionToServer.ExecuteAsync(cmd) )
{
    Monitor.Wait( this.WillBePulsedBy_SomeCmd_OnCompleted );
}

Here is a greatly simplified version of my base classes, but you can see how it works:

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();
}

解决方案

throwing an exception from the dispatch point may or may not be useful

calling the callback passing an exception argument requires the completion callback to do 2 distinct things

a second callback for exception reporting might make sense instead

这篇关于异步命令模式 - 异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆