2012-08-05 52 views
0

我在Windows Phone 7应用程序中使用伪同步套接字。我的套接字代码基于http://msdn.microsoft.com/en-us/library/hh202858(v=vs.92).aspx的示例。终止套接字操作Windows Phone

服务器的发送模式有点不可预知。它以包含消息其余部分的长度的固定大小头开始。我首先在这个头文件中读取,然后从套接字读取指定的字节数。

因为我需要将消息发送到服务器,以及,我试图在与接收线程和另一个线程发送双工插座引起很多问题,我有这样的在我的代码回路:

while (KeepConnectionGoing) 
     { 
      byte[] Rcvd; 
      Rcvd = Socket.Receive();//Returns null if no message received in 50 ms 
      if (Rcvd != null) 
      { 
       ParseMessage(Rcvd); 
      } 

      if (HasMessageThatNeedsToBeSent()) 
      { 
       byte[] Message = GetMessageToSend(); 
       Socket.Send(Message); 
      } 
     } 

这对大多数时间都适用,但当消息为空时会发生奇怪的事情。 由于Receive方法中的超时(请参阅链接的示例)使用ManualResetEvent,套接字上的接收请求实际上从未取消。即使该方法返回,该请求也会在某个地方等待,并且当套接字上有数据时,请重新标题。事件处理程序与接收到的数据无关(因为该方法已返回并且方法中的变量将永远不会再使用),数据基本上消失。我希望返回标题跳读的读请求读取标题后面的字节,并且我不知道该消息有多长。

我希望能够取消所有未完成的请求,如果套接字超时。我使用类似于示例中的匿名方法,因为它简化了一切,并防止我自己编写所有状态传输代码。因此,我无法解开事件处理程序。我认为,即使我使用方法作为事件处理程序,但在异步操作完成之前解除绑定,仍将调用回调方法。现在(我没有测试过这一点,这只是我的理解)

,唯一的解决办法,我可以看到的是一些静态的字节数组黑客在一起(即具有静态的byte []头,如果是空的,我阅读标题,否则我读取消息),但这似乎是一个非常不雅的解决方案,很容易出现竞争状况。

有没有更好的方法?

谢谢

回答

0

看来真的没有好办法做到这一点。轮询方法很好,但Silverlight没有它。我使用静态标志一起攻击了一个解决方案,告诉我我处于什么状态(请求标头,请求消息),长度的静态int和静态缓冲区。

在方法开始时,可​​以请求标题或正文。如果头部已被请求,则线程将等待有效的身体长度可用。如果等待超时,这意味着头部接收操作仍在等待处理,但实际上没有消息可用。否则,它会读入该消息的长度。

如果头没有被请求,接收头。在事件处理程序中,完成后,检查控制流是否已经继续(即接收操作花费的时间太长,所以函数已经返回,但现在已经完成)。更新长度,然后请求主体,除非超时。