为什么Thread.Abort只有在isBackground属性设置为true时才有效?

时间:2014-03-31 13:17:50

标签: vb.net multithreading vb.net-2010

我正在开发一个小型UDP控制台来发送一些数据来测试一些GPRS设备,所以我修改了一个我在CodeProject中发现它使用一个线程的例子;但是当我想要退出应用程序时,我遇到了问题,即使我做了像

这样的事情,treahd也拒绝停止
If UdpOpen Then
   ThreadReceive.Abort()
   Me.Dispose()
   UdpOpen = False
End If

它停在第一个代码行

Private Sub UdpReceive()
    Dim receiveBytes As [Byte]() = receivingUdpClient.Receive(RemoteIpEndPoint) '<--Halt here
    IpRemote(RemoteIpEndPoint.Address.ToString)
    Dim BitDet As BitArray
    BitDet = New BitArray(receiveBytes)
    Dim strReturnData As String = System.Text.Encoding.ASCII.GetString(receiveBytes)
    If UdpOpen Then
        StartUdpReceiveThread(CInt(RemotePortLbl.Text))
    End If

    PrintLog(strReturnData)
End Sub

所以我做了一些研究,通常在这个网页上找到了解决方案 Stop a thread that prevents program to close?

而且,正如第一条评论中所述,我转向True isBackground属性并且它有效,现在问题是为什么?

有人深入了解它的工作原理吗?

2 个答案:

答案 0 :(得分:7)

当CLR知道这样做是安全的时,线程才可以中止。当线程深埋在操作系统调用中时,情况不会如此。这基本上是不安全的,因为CLR无法知道线程是否已获取需要再次释放的任何内部操作系统锁。

通过将IsBackground属性设置为 true ,您告诉CLR可以中止的线程,但将其留给操作系统进行清理任何需要释放的东西。任何采取的锁都不会导致任何问题,因为任何代码都无法再运行可能会死锁。操作系统负责释放套接字使用的OS资源。就像你的程序因任何其他原因而中止一样,就像你用任务管理器终止它一样。

执行此操作的正确方法是只调用套接字的Dispose()方法。这会拉动操作系统调用的地垫,它将停止等待接收任何东西,因为套接字是死鹦鹉。 Receive()调用将以ObjectDisposedException完成,准备捕获它。

另一个非常常见的情况是根本不使用线程而是使用BeginReceive()。清理工作方式大致相同,当您调用Dispose()时,回调将运行。当您调用EndReceive()时,您将获得ObjectDisposedException。同样的方式,准备抓住它并快速离开而不用插座做任何其他事情。

使用Thread.IsBackground是处理关闭的一种非常合理的方法,假设你不必做任何复杂的事情来告诉你在线路的另一端停止监听消息的程序。

答案 1 :(得分:2)

.NET内置支持异步接收UDP。见:

所以在这种情况下你不需要使用线程。