2013-03-23 59 views
0

由于某种原因,调用Thread.Join()时无法结束线程。我疯了吗?线程看不见全局布尔值

Public Sub StartThread() 
    _opsthread = New Thread(AddressOf OpsThread) 
    _opsthread.IsBackground = True 
    _opsthread.Start() 
End Sub 

Public Sub StopThread() 
    _continue = False 
    _opsthread.Join() 
    'Application Hangs Here 
End Sub 

Public Sub OpsThread() 
    While _continue 
     Thread.Sleep(1000) 
    End While 
End Sub 
+0

我测试了写入的代码,但无法重现挂起。我同意应该以不同的方式访问继续标志。 – dbasnett

+0

对不起,我简化了代码,因为我认为没有人会想要阅读3页代码,无论我多么努力地尝试没有优雅。 – wayofthefuture

+0

然后简化版本不代表问题。 – dbasnett

回答

1

这是我跑过的测试,稍作修改。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Button1.Enabled = False 
    StartThread() 
End Sub 

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    StopThread() 
End Sub 

Dim _opsthread As Threading.Thread 
Dim _continue As New Threading.AutoResetEvent(False) 

Public Sub StartThread() 
    _continue.Reset() 
    _opsthread = New Threading.Thread(AddressOf OpsThread) 
    _opsthread.IsBackground = True 
    _opsthread.Start() 
End Sub 

Public Sub StopThread() 
    If IsNothing(_opsthread) Then Exit Sub 
    _continue.Set() 
    _opsthread.Join() 
    'Application Hangs Here 
    ' Debug.WriteLine("end") 
End Sub 

Public Sub OpsThread() 
    Dim cont As Boolean = False 
    While Not cont 
     cont = _continue.WaitOne(1000) 
    End While 
End Sub 
+0

我声明继续像这样:Private _continue as boolean – wayofthefuture

+0

我重新定义了照顾同步。 – dbasnett

+0

它现在正在工作!我将_continue从全局布尔值更改为autoresetevent并解决了问题。谢谢! – wayofthefuture

0

您尚未同步访问_continue。出于这个原因,它可能是由JIT注册的。在读取它之前和写入之前,同步对它的访问(例如使用Thread.MemoryBarrier)。

不同步共享数据总是一个红旗。不管是因为程序变得越来越小,还是因为大多数人不能很好地理解规则以确保它是安全的(我当然不会 - 所以我不这样做)。

+0

你有一个例子吗?谢谢。 – wayofthefuture