2012-08-05 51 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和靜態緩衝區。

在方法開始時,可​​以請求標題或正文。如果頭部已被請求,則線程將等待有效的身體長度可用。如果等待超時,這意味着頭部接收操作仍在等待處理,但實際上沒有消息可用。否則,它會讀入該消息的長度。

如果頭沒有被請求,接收頭。在事件處理程序中,完成後,檢查控制流是否已經繼續(即接收操作花費的時間太長,所以函數已經返回,但現在已經完成)。更新長度,然後請求主體,除非超時。