本帖最后由 changetry 于 2011-07-30 10:30:42 编辑

解决方案 »

  1.   

    你的locker和locker1是不是一个东西,如果是一个的话,SEND线程一直锁着,receive线程当然就拿不到了。
     建议改用ManuResetEvent自定义锁定事件及解锁,省得琢磨这些东西,自动化的玩意有时就是不好使
      

  2.   


    补充一点:我认为,这个简单的说就是阻塞。就是当发出指令后,阻塞起来等待,不执行下面的代码,当接受到Pulsh的时候,再继续执行下面的代码
      

  3.   


    一样的。信号量阻塞也是Monitor阻塞。
      

  4.   

    一个异步编程的思维是这样的,类似于send();
    BeginReceive(callback);也就是说,在Send之后,注册了Receive的监听回调(这只需要一瞬间),然后程序就执行完了,结束了。而不是阻塞着当前的线程。实际上更加高效的异步编程是类似于:BeginSend(sendCallback);然后再sendCallback中才去进行异步读数据操作。也就是说连send也应该是异步的,而不是让线程阻塞这里等待send操作结束(因为它其实不占CPU,主要是底层驱动和硬件去执行)。以前在csdn上F#曾经火过一阵子,现在在ajax也火。但是其涉及异步操作时,有不少人还是拿着传统的函数式编程的思维去写代码,这就会有很多莫名其面难以调试的bug出来。函数式思维不适合这个多线程、异步编程的时代需要。异步编程都是把回调提前注册给执行异步操作的方法,而不是阻塞在那里等待函数(方法)返回一个值之后继续执行。所以如果你逻辑上就是习惯于函数式思维,就要从逻辑上改变设计习惯,这样才能方便于编程和调试。
      

  5.   

    你去调用send,然后等这个方法执行完继续向下执行;你去掉用recceive,然后等这个方法执行完再继续向下走去处理结果........这整个是个顺序编程的思维,硬要赶多线程编程的时髦,那就不得不拿阻塞方法来自我安慰了。实际上,阻塞方法,就是拿着线程的样子,来搞顺序编程。本质上并没有什么提高。
      

  6.   

        阻塞和回调在核心上使用的技术是一样的,都是注册一个WorkItem,符合条件时发起这个WorkItem,所不同的是,阻塞的释放是原有方法的继续,而回调释放是新方法的开始。
        可以看到,在阻塞时,需要考虑超时等待失败的问题,因此使用循环配合阻塞还可以替代诸如一些定时器应用,因为定时器的缺陷是每次都发起新的操作,有时会造成“撞车”,而循环配合阻塞可避免这个问题。
      而回调就具有阻塞一些无法比拟的优势,使用回调可以大幅度的节省线程的资源,因为我们在send线程上完成后,该线程就可以释放掉了,而另一个接收线程的启动是由信号时才进行。而阻塞则就得长期占用两个线程。
      因此,在通信领域,使用回调效率要高于阻塞,而阻塞也有其他方面的很多用途。
      

  7.   

    我理解的你的意思了。我的情况,怎么说呢?我是通过委托链来统一分发服务器返回的结果,当然在之前的操作是异步的,一些很常用的socket编程方法。但是,我把返回的结果,通过标识,来让客服端表示层识别是自己发的什么指令返回的结果,然后我只要+=委托事件,就可以通过指令标识获取结果,然后处理。这样的一个统一的分发模式。我上面的是一些代码段,也许有点表达不全。
    所以:我发送指令后,我需要获取结果,然后跟据结果和其他信息(必须发送指令前收集处理后的信息),来做下一步操作。so, 当我从委托事件中知道结果后,我就需要通知他继续执行下去,此处需要阻塞一下。
      

  8.   

    另外,socket的自带的异步操作与我们使用的事件注册与回调还是有区别的,我们自己注册的事件在一个线程(假设为A)中被激发后调用的回调时,所执行执行回调函数的线程时线程A,而Socket异步调用的回调是WorkItem发起的,因此效率要高出很多,
      有些程序员不太理解时使用的回调,就会造成你程序的状态:“互锁”,这是应该注意线程A发起回调后,最好再单独启动一个线程执行具体的回调,以保证线程A不受到阻塞。
      另外,我个人理解线程在阻塞中,并不占用CPU资源,所占用的是线程栈的内存资源,因此,在在线用户不大情况下,阻塞的效率并不比回调差,可能由于减少了线程的释放与加载,性能还会强些,但如果数量较大,如500个在线链接,每个连接两个线程,那么总共光收发线程就需要2GB内存,把系统内存都吃光了,系统自然就扛不住了。
      

  9.   

    近一段时间做了一个网页抓取+分析的项目,正好用到了一些这方面的技术,我个人的观点是,涉及到IO操作的部分,尽量使用异步,比如用网络传输数据,向硬盘写文件,访问一些外设之类的。因为Windows对于IOCP的支持,采用异步方式比多线程同步可能更有效率,另外在使用WebClient或HttpWebRequest下载东西时,异步方式的成功率更高(这个是我自己实验的,非官方说法,不一定靠谱)。相比于多线程同步,异步方式可以减少使用线程资源,不过同样需要控制并发数量,更重要的是,有时你需要主动Cancel掉某些异步操作,以免出现超长时间的等待,并且不释放资源。其他情况下,比如BeginInvoke,主要也是依靠线程池实现的,这种情况下两者差别就不太大了。
      

  10.   

    客户端不会太多的。如果一个服务器所对应客户端超过500的话,估计会震惊的,异步方式的确好用,这深有体会的。昨晚根据项目,拆分了一个个小Demo做,最后慢慢折腾好了,散分吧。谢谢@litaoye,@etudiant6666,@sp1234