rtdb,谢谢你的答复,我的客户端应该在10个左右,我很担心在往concurrentdictionary里面会写数据的时候会不停的有加锁解锁的过程,这样不会造成性能问题么?

解决方案 »

  1.   

    我说的数据还是考虑到了网络及系统整体响应速度。若只是concurrentdictionary的加锁解锁,
    呵呵你太小看现在的CPU速度了,
    你可以自己测试一下,我相信每秒十万上下只是起步。
      

  2.   

    RTDB,那我这样设计没问题吧,或者你还有什么更好的建议么?我自己纠结了这个问题好久,一直觉得性能没达到最佳。
      

  3.   

    不精通SOCKET的话,还是用WCF,小规模应用(10客户端)根本不用考虑太多,但回发需要注意,不能使用单线程(可用线程池或多线程),否则中途某个客户端的网络故障会导致后面其他客户端晋重延迟。
      

  4.   


    YCG_893,谢谢,我明白了,我不用担心性能问题了。还有个附加问题,你说的回发时使用多线程是不是指在server端当我callback每个客户端时都使用独立的线程来完成针对每个客户端的调用?
      

  5.   

    Hi,ycg_893
    我在server端有个方法实现的就是遍历所有客户端,然后给所有客户端发命令,代码如下 public void KickoffTest()
            {
                  foreach (var item in Clients)
                {
    //我该在这里用多线程来实现么?
                    item.Key.SendRequestToClient("Begin Testing");
                }
            }
    不是在这里发命令时候要用多线程去实现?
      

  6.   

    如果你的客户端都只向服务器获取数据,这个就不存在回发问题,因为是单向的,若需要服务器也向客户端发送数据则是双向的(WCF双工通信),服务器主动发给客户端就需要注意,假设100个客户端,发到50个的时候阻塞了或者需要待到超时异常(如果不处理异常,那每51个以后都收不到)后第51个才开始发送,阻塞时间根据网络情况和超时时间确定,即使没有发生这种情况,若每一个客户端需要2秒,是不是第100个客户端需要几分钟后才接到;使用多线程或线程池也取决于你的客户端规模,若有几千个客户端,每次每个需要一个线程的话,估计你的服务器无法承受,会因线程耗尽而崩溃。关于线程问题不是几句话就完全说明清楚,这跟规模、设计、需求有关;至于配置WCF服务器也有关,如单实例、一个会话一个实例、还是每次都是一个实例、要不要同步上下文等;详看WCF配置你上面的代码可以简单地在循环内加线程,但这种仅作为测试还可以,实际部署应用你可以多尝试各种故障测试就知道不可行。
      

  7.   

    还需要做线程安全方面,如发送时有100个,但正在发送的,有注销退出的。按你的代码就会产生“枚举的集合已变动的异常”。也不应该说等我发完了你再退出,这当然不合理,可以简单地解决就是复制一个数组出来,实际上复制数据时就需要线程安全。如下简单示例:      iCallBack[] ClientKeys;
          lock(lockObject)
             {
                ClientKeys = Clients.Keys.ToArray();
             }
          foreach (var item in ClientKeys)
                 {
                   //新线程或加入线程池
                      item.SendRequestToClient("Begin Testing");
                 }
     
      

  8.   

    ycg_893 , 谢谢你不厌其烦的指点,我大概知道怎么弄了,能不能等我实现了再给我看下?我能晚点结分给你行么?
      

  9.   


    namespace WCFLib
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
        public class Publisher : IPublisher
        {
            private static readonly ConcurrentDictionary<iCallBack, Package> Clients = new ConcurrentDictionary<iCallBack, Package>();
            public void Register()
            {
                var client = OperationContext.Current.GetCallbackChannel<iCallBack>();
                if (!Clients.ContainsKey(client))
                {
                    Clients.TryAdd(client, new Package(DateTime.Now));
                }        }         public void SendHeartbeatPackage()
            {
                var client = OperationContext.Current.GetCallbackChannel<iCallBack>();            if (Clients.ContainsKey(client))
                {
                    Clients[client] = new Package(DateTime.Now);
                }            Console.WriteLine("Begin to update heartbeat package.");
                Console.WriteLine("Updated time is {0}", (Clients[client] as Package).Time);
            }     }
    }Reentrant 模式下 并不是真正的并发吧? 改成multi的 你的Register 方法就不对了
      

  10.   

    这。
    不会的 只要不是
    while(true){
      //心跳包发送
    }
    就不会出问题另外一分钟发一个也没有问题