你满脑子是顺序编程的思路,根本没有接受异步操作的概念。所以才会自己发明了“成EndReceive永久性的阻塞”这种无厘头的说法。只要执行ReceiveAsync,这个方法就立刻结束了。你线程所调用的方法都结束了,还把什么弄到线程里?你最后这个纠结实在是匪夷所思。

解决方案 »

  1.   

    这个说法有点抬杠了 主动的结束BeginReceive操作 和BeginReceive在不能完成的情况下自动结束操作是两个概念恰恰我目前做的项目中需要后者的功能那么有没有一个c#提供的被动方法 例如设置timeout的方法来规定异步recv超时后自动返回的方式呢?还有我提问的问题 ReceiveAsync 的操作到底是加入线程池还是创建新线程操作 这个是我关心的
      

  2.   

    udpclient的BeginReceive没有说明超时时间 但是MessageQueue.BeginReceive的方法说明为 "启动一个没有超时设定的异步接收操作。直到队列中出现消息时,才完成此操作。"我不能把MessageQueue的定义强加到udpclient上 但我实际测试 udpclient的BeginReceive 如果服务端无数据返回 可以阻塞1个小时左右 再长的时间没有试 最后感慨一下 不知道为什么 在CSDN提问 下面的回答经常似是而非 每个程序都有自己的功能需要 也许你的方案本身是好的 但是放在一个整体项目中是不合适的 很多次提问 提问的主要问题没人回答 而是针对问题本身过程展开讨论 弄的我很纠结
      

  3.   


    Task<UdpReceiveResult> udpRR = udpSend.ReceiveAsync();
    //udpRR.IsCompleted==false;
    Thread.Sleep(1000);
    //udpRR.IsCompleted==true; 你说的没错 udpSend.ReceiveAsync();是异步立即返回的 那么中间Sleep了1秒 系统到底做了什么?
    是创建了新线程recv 或者是把recv操作加入了线程池?
    因为两个操作的系统开销差异是很大的 考虑到系统性能才有此一问
      

  4.   


    什么意思?BeginReceive操作可能需要5毫秒就结束了。然后过了10秒钟,操作系统在它自己分配的某一个线程中调用了EndReceive。或者干脆是uc根本就已经被GC回收了,永远不可能调用什么EndReceive了。你难道以为BeginRecive是阻塞在那里10秒钟?你这不是顺序编程是什么?这完全是不理解异步操作才会有的想法。
      

  5.   

    上面代码写错了
    Task<UdpReceiveResult> udpRR = udpSend.ReceiveAsync();
    udpRR.Start();//少了这句Task没有运行
    //udpRR.IsCompleted==false;
    Thread.Sleep(1000);
    //udpRR.IsCompleted==true; 
      

  6.   


    这是你刚刚整出来的代码,你的问题中并没有这个什么 Sleep(1000)。我也是刚刚回复完#6楼之后才看到你的#5楼的内容!这个Sleep(1000)谁知道是干什么的?是你自己贴出来的代码,你才应该给出它的出处的说明啊,难道让我告诉你出处?
      

  7.   

    其实你整的既然就是“异步”,那么上下两个代码都是一样的概念。除非你打算执行 uc.Receive(...),这次是同步顺序阻塞的,这才涉及到弄一个线程来执行它的意思。你这时候才值得去担心“这个线程中的代码会无限等待下去”的问题。但是当你要阻塞的时候,这就跟异步操作完全是两回事了。比如说同时有1000个客户端会话,使用15个线程可能就足够应付的了,而你的同步顺序阻塞方式则需要占用1001个线程。
      

  8.   

    咱俩说的是两个问题 public IAsyncResult BeginReceive(AsyncCallback requestCallback, object state);BeginRecive是立即返回的 但是requestCallback在服务端没有数据返回的情况下 永远不会被调用
    我所说的阻塞 不是BeginRecive本身操作的阻塞
      

  9.   

    AsyncCallback   是由线程池调用的。 不过是系统管理的效率高很多。 如果你要取消挂起的begineXX  可以用close关闭调用begineXX的IO对象。