1

我希望使用 .NET 进行同步通信(通过串行)SerialPort,也希望使用 .NET 进行异步通信(通过以太网)Socket

当前的实现有一个 Connection 类,它声明了 aSerialPortSocket,并且根据用户在 GUI 中定义的设备连接类型(COM 或以太网),Connection 类将初始化适当的串行或套接字端口。

我有一个包含所有连接的 ConnectionManager。因此,如果用户使用相同的连接信息创建设备,它不会创建新的连接;相反,它只是分配了在 ConnectionManager 中找到的连接。

这是一个问题,因为我需要进行同步通信和异步通信。发生的情况是有一个循环Task在我连接到设备时创建 s 并且每个Task人都在尝试执行Sendand Receive,并且由于设备完成任务需要更长的时间,而不是软件创建任务所需的时间,所以是很多并发问题(阻塞线程)。由于我需要进行同步通信,因此我Mutex在发送之前锁定了一个Send互斥锁,并在我的 -- 之后释放了互斥锁,Receive以确保每次发送我都会收到一个接收。这不好,因为当我尝试进行异步通信时,它将由于互斥锁而受到限制。

所以我的问题是,当尝试同时处理异步和同步通信时,最好的设计是什么?是否应该有两个不同的连接类(AConnection、BConnection)继承具有 Send、Receive、Open、Close 方法的 Connection 接口?

任何帮助表示赞赏。

4

1 回答 1

3

通常,您应该始终更喜欢对象组合而不是类继承。这意味着,与其创建一个WorkClass具有您需要的大部分功能的超类(例如 ),然后创建两个从它继承的具体子类(例如AWorkClass : WorkClassBWorkClass : WorkClass)并使用/覆盖这些功能,您应该创建两个具体的没有继承(AClassBClass)的类“有”WorkClass作为成员变量。

更进一步,最后试图回答你的问题,听起来你想实现策略模式,它允许你非常轻松地切换“策略”(比如在同步和异步通信之间),并允许你添加新的“策略”无需太多努力(或对现有策略进行修改而不必担心连锁反应)。

这是用 C# 实现的示例策略:

namespace Your.App
{
//correct implementation of the Strategy Pattern
    interface ICommunication
    {
        void Send();
    }
    class SyncCommunication : ICommunication
    {
        public void Send() { /*your sync code*/ }
    }
    class AsyncCommunication : ICommunication
    {
        public void Send() { /*your async code*/ }
    }
    public class WorkClass
    {
        ICommunication Strategy { get; set; }
        public WorkClass()
        {
            UseAsync = false;
        }
        bool _useAsync;
        public bool UseAsync 
        {
            get { return _useAsync; }
            set
            {
                _useAsync = value;
                if(_useAsync)
                    Strategy = new AsyncCommunication();
                else
                    Strategy = new SyncCommunication ();
            }
        }
        public void Send()
        {
            Strategy.Send();
        }
    }
}

要将其与第一段联系起来,然后像这样使用 WorkClass:

namespace Your.App
{
//correct implementation of the Strategy Pattern
    public class MyWorkContext
    {
        WorkClass Worker {get; set;}
        public MyWorkContext()
        {
            Worker = new WorkClass();
        }

        public void SendMyData()
        {
            if(someConditionIsMet)
                Worker.UseAsync = true;
            else
                Worker.UseAsync = false;
            Worker.Send();
        }
    }
}

您可以看到您的用户WorkClassMyWorkContext在这种情况下)对您的策略一无所知,也不应该知道。它只是告诉工人足以让其知道该做什么,然后工人知道它需要使用哪种策略来完成它。策略本身是唯一知道工作实际如何完成的策略这对于测试和维护非常有用。

于 2012-09-20T23:58:37.203 回答