如何使用事件数组处理传入的命令?

时间:2012-10-08 22:16:41

标签: c# tcp event-handling

我目前正在开发一个简单的客户端/服务器模型,它在TCP数据包(如HTTP)中发送数据包,命令基本上是整数(每个数据包的前4个字节),我想找到一个有效的如何处理这些命令的方法。

最明显的答案是编写成千上万的if或者用千个案例做一个巨大的switch语句,但是没有更好的方法吗?

我想创建一个事件数组,然后只提高相应的索引,以便每个int引用一个被命名的事件(例如MessageReceived)。我也想节省时间,所以我怎么能解决这个问题呢?

编辑:服务器处理多个连接,每个连接一个连接的客户端,因此在我的情况下为每个命令创建单独的连接并不是很有用。

2 个答案:

答案 0 :(得分:3)

听起来像是枚举工作!

enum YourEnum   
{
  DoThis,
  DoThat
}

YourEnum foo = (YourEnum)yourInt;

Visual Studio甚至可以使用内置的代码段创建整个switch语句,并且您的代码变得非常易读。

switch(foo)

变为

switch(foo)
{
  case YourEnum.DoThis:
    break;
  case YourEnum.DoThat:
    break;
  default:
    break;
}

更新1

从可维护性的角度来看,这有点可怕,但如果你创建了一个类:

public class ActionProcessor
{
  public void Process(int yourInt)
  {
    var methods = this.GetType().GetMethods();
    if (methods.Length > yourInt)
    {
      methods[yourInt].Invoke(this, null);
    }
  }

  public DoThis()
  {
  }

  public DoThat()
  {
  }

或者更好但更难维护:

[AttributeUsageAttribute(AttributeTargets.Method, 
                         Inherited = false, 
                         AllowMultiple = false)]
public sealed class AutoActionAttribute : Attribute
{ 
  public AutoActionAttibute(int methodID)
  {
    this.MethodID = methodID;
  }
  public int MethodID { get; set; }
}

public class ActionProcessor
{
  public void Process(int yourInt)
  {
    var method = this.GetType().GetMethods()
      .Where(x => x.GetCustomAttribute(typeof(AutoActionAttribute), 
                                       false) != null
                  && x.GetCustomAttribute(typeof(AutoActionAttribute), 
                                       false).MethodID == yourInt)
      .FirstOrDefault();

    if (method != null)
    {
      method.Invoke(this, null);
    }
  }

  [AutoAction(1)]
  public DoThis()
  {
  }

  [AutoAction(2)]
  public DoThat()
  {
  }
}

更新2 (编码我认为Josh C.正在谈论的内容)

// Handles all incoming requests.
public class GenericProcessor
{
  public delegate void ActionEventHandler(object sender, ActionEventArgs e);

  public event ActionEventHandler ActionEvent;

  public ProcessAction(int actionValue)
  {
    if (this.ActionEvent != null)
    {
      this.ActionEvent(this, new ActionEventArgs(actionValue));
    }
  }
}

// Definition of values for request
// Extend as needed
public class ActionEventArgs : EventArgs
{
  public ActionEventArgs(int actionValue)
  {
    this.ActionValue = actionValue;
  }

  public virtual int ActionValue { get; private set; }
}

这将创建负责某个值的SomeActionProcessor:

// Handles a specific (or multiple) requests
public class SomeActionProcessor
{
  public void HandleActionEvent(object sender, ActionEventArgs e)
  {
    if (e.ActionValue == 1)
    {
      this.HandleAction();
    }
  }

  private void HandleAction()
  {
  }
}

然后创建类并连接它们:

GenericProcessor gp = new GenericProcessor();
SomeActionProcessor sap = new SomeActionProcessor();
gp.ActionEvent += sap.HandleActionEvent;

火灾并发送通用处理器请求:

gp.ProcessAction(1);

答案 1 :(得分:1)

您可以实施发布商订阅者模型。没有一个听众,你会有很多。每个监听器都会监听至少一个命令。然后,您可以将交换机拆分为多个类。