2010-12-20 106 views
1

出於某種原因,我需要做的BeginReceive在一個單獨的線程,就像這個例子:BeginReceive在一個單獨的線程

public void WaitForData() 
    { 
     Thread t = new Thread(WaitForDataThread); 
     t.Start(); 
    } 

    public void WaitForDataThread() 
    { 
     try 
     { 
      CSocketPacket theSocPkt = new CSocketPacket(); 
      theSocPkt.thisSocket = m_socClient; 
      m_asynResult = m_socClient.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, OnDataReceived, theSocPkt); 
     } 
     catch (SocketException se) 
     { 
      MessageBox.Show(se.Message); 
     } 
    } 

但BeginReceive通話之後我一直收到錯誤,OnDataReceived是立即引發,在這種情況下,它將調用EndReceive方法,並且始終拋出此錯誤:「由於線程退出或應用程序請求,I/O操作已中止」。

但是,如果我刪除單獨的線程部分(如直接調用WaitForDataThread(),而不通過WaitForData()方法),一切工作正常。

如果您想知道爲什麼我需要創建一個單獨的線程,這是因爲我需要在從另一個類中的不同線程生成的事件期間調用BeginReceive。這與創建像上面示例這樣的新線程非常相似,並且我需要使其工作。

有沒有一種方法可以做到這一點?

+0

我真的不明白爲什麼你必須創建一個新線程來啓動異步操作? – Jan 2010-12-20 17:44:14

+0

我需要模擬其他類中的不同線程事件,因此創建新線程並調用BeginReceive與在不同線程中生成的事件中調用它相同。 – 2010-12-20 17:49:10

+0

好吧,明白了:)看我的回答 – Jan 2010-12-20 18:15:51

回答

2

找到了答案上msdn(Socket.EndReceive的文檔):

所有I/O由給定線程發起的 取消當線程退出。如果線程在 操作完成之前退出,則 掛起的異步操作可能會失敗 。

您必須確定,在開始套接字操作之前,您的線程在您完成套接字I/O之前不會退出。

解決方法是使用線程池線程,如here所述。

+0

嗨,謝謝你的回答,就在這個圓點上!謝謝... – 2010-12-20 18:29:23

1

我假設你的主線程不會等待數據到來,而是在產生另一個線程後退出。完成主線程會殺死整個應用程序,所以你的WaitForData線程也會死掉。

你必須做到以下幾點:

  1. 啓動WaitForData線程
  2. 什麼就做什麼主線程要
  3. 等到主線程(在的Thread.join WaitForData線程結束? )
  4. 然後退出。
+0

嗨,這不是一個控制檯應用程序,這是一個Winforms應用程序。這有什麼區別? – 2010-12-20 17:52:50

+0

好吧,它會有所作爲。基本規則保持不變:您需要確保主線程在您的WaitForData線程完成之前不會退出。你確定你打開窗戶嗎? – Vlad 2010-12-20 17:55:35

+0

是的,窗口仍然打開,應用程序仍在運行。有沒有辦法從它的原始線程調用BeginReceive?我假設我將不得不保留一些循環來保留原始線程... – 2010-12-20 18:09:55

相關問題