2013-03-23 58 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