我正在开发一个小型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
所以我做了一些研究,通常在这个网页中找到解决方案 停止阻止程序关闭的线程?
并且,正如第一条评论所述,我转向True isBackground属性并且它有效,现在的问题是为什么?
有人深入了解它的工作原理吗?
当CLR知道这样做是安全的时,线程只能被中止.当线程深埋在操作系统调用中时,情况不会如此.这基本上是不安全的,因为CLR无法知道线程是否已获得需要再次释放的任何内部操作系统锁.
通过将IsBackground属性设置为true,可以告诉CLR可以不中止线程,而是将其留给操作系统来清理需要释放的任何内容.任何采取的锁都不会导致任何问题,因为任何代码都无法再运行可能会死锁.操作系统负责释放套接字使用的OS资源.就像你的程序因任何其他原因而中止一样,就像你用任务管理器终止它一样.
正确的方法是调用套接字的Dispose()方法.这会拉动操作系统调用的地垫,它将停止等待接收任何东西,因为套接字是死鹦鹉.Receive()调用将以ObjectDisposedException完成,准备捕获它.
另一个非常常见的情况是根本不使用线程,而是使用BeginReceive().清理工作方式大致相同,当您调用Dispose()时,回调将运行.当您调用EndReceive()时,您将获得ObjectDisposedException.同样的方式,准备抓住它并快速离开而不用套接字做任何其他事情.
使用Thread.IsBackground是处理关闭的一种非常合理的方法,假设你不必做任何复杂的事情来告诉你停止侦听消息的另一端的程序.