Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用事件数组处理传入命令?_C#_Tcp_Event Handling - Fatal编程技术网

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

C# 如何使用事件数组处理传入命令?,c#,tcp,event-handling,C#,Tcp,Event Handling,我目前正在开发一个简单的客户机/服务器模型,它在TCP数据包(如HTTP)中发送数据包,命令基本上是ints(每个数据包的前4个字节),我想找出一种有效的方法来处理这些命令 最明显的答案是写上千个if,或者用上千个case做一个巨大的switch语句,但是没有更好的方法吗 我想创建一个事件数组,然后提高相应的索引,使每个int引用一个命名的事件(例如MessageReceived)。我想我还可以节省时间,那么我该如何解决这个问题呢 编辑:服务器处理多个连接,每个连接的客户端一个连接,因此在我的情

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

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

我想创建一个事件数组,然后提高相应的索引,使每个int引用一个命名的事件(例如MessageReceived)。我想我还可以节省时间,那么我该如何解决这个问题呢


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

听起来像是枚举的工作

enum YourEnum   
{
  DoThis,
  DoThat
}

YourEnum foo = (YourEnum)yourInt;
VisualStudio甚至可以使用内置的代码段创建整个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.所说的内容)

这将创建负责某些值的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);

您可能会实现发布者-订阅者模型。你会有很多听众,而不是一个听众。每个侦听器将侦听至少一个命令。然后您可以将交换机拆分为多个类。

如果它们在某种程度上按逻辑分组(如HTTP代码),您应该能够嵌套
If
块。尝试围绕其底层逻辑构建代码。如果您有一组连续的
int
,那么您应该有一组连续的
If
case
语句。您如何知道哪个代码对应于哪个事件?你一定在某处有个定义。。。对吗?你真正想要的是一个状态机,它是用于这种情况的。忘掉if语句,看看如何做状态机。嘿,谢谢你的回答,我以前做过。然而,毕竟我必须使用这个开关,它有上千个if的负载,如果把所有事件放在一个数组中,然后只处理相应事件的索引,不是更有效吗?再一次,非常感谢!更新使用一些反射的东西作为另一个选项。哦,哇,好的!好吧,我想我会选择第一个选项,因为我不想把所有这些方法都放在Client.cs类中:)谢谢你的努力!这还可以使用反射来确定要使用反射进行实例化的类(而不是方法),并以您想要的任何方法将数据传递给该类。它不限于一个班级。啊,是的,好主意!另外,在这种情况下,不必(yourInt)是(yourInt+1),因为“Process”是第一个方法?对不起,我对这个主题不太了解,所以我只是想知道这些方法是按顺序还是按字母表列出的?这也是事件的基本概念,不是吗?谢谢你的回答:)嘿,谢谢你的回答。然而,我已经有了一个服务器,每个客户端都有一个连接,我认为如果每个命令都有一个单独的连接,那就有点过分了,如果这就是你的意思的话。谢谢你@hl2mukkel那么为什么不在客户端中实现观测者模式/发布者订阅服务器呢。客户端可以包含一个实现发布者类的连接。然后,您有许多订阅服务器类,这些订阅服务器类都在客户机中订阅一个发布服务器。
gp.ProcessAction(1);