2010-12-20 108 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

相关问题