2013-10-17 31 views
1

我的項目是vb.net 2010的Windows桌面形式。 到目前爲止,單線程(默認)。螺紋。如何按鈕點擊中斷/影響程序流程

如果一個子程序的一對......在它下一個循環運行,如果ButtonClick事件被觸發會發生什麼以及該事件中的變量發生變化?像:程序執行離開正在運行的循環嗎?還是繼續運行,而該變量是由buttonclick事件改變的?

我的目標是什麼了: 如果有人點擊該按鈕,blnRequestStop設置爲True。 對於...下一個循環,在「next」之前它檢查blnRequestStop。如果爲true,那麼它將退出「for」循環。

我猜我需要使用線程?任何人都可以給我一個簡單的例子嗎?

編輯: 此代碼低於似乎工作正常。但是,也許你都看到一個問題?

If (btnProcess.Text = "Done!") Then 
    End 
ElseIf (btnProcess.Text = "IMPORT") Then 
    bRequestStop = False 
    t1 = New Thread(AddressOf ProcessDo) 
    t1.Start() 
Else 
    t2 = New Thread(AddressOf MyInterrupt) 
    t2.Start() 
End If 

這裏是什麼ProcessDo和MyInterrupt做短版:

Private Sub ProcessDo() 
    For each X in blahblah 
     'do stuff (yes, includes interface) 
     if (blnInterrupt) then exit For 
    Next X 
    End 
End Sub 

Private Sub MyInterrupt() 
    blnInterrupt=true 
End Sub 
+3

這聽起來像你在UI線程中有一個長期運行的任務。基本上你不應該這樣做...... –

+1

當你點擊一個按鈕時,所發生的事情就是排隊(不是即時運行)。一旦你的GUI線程(你的'Form'是new Form(「form1」)''d')的線程可用(空閒),它將讀取隊列並運行你的按鈕單擊事件。你的GUI線程將不會閒置直到它退出For ... Next SUB(我已經習慣了C#,否則我會用代碼來回答)看看這個http://msdn.microsoft.com/en-us/library/dd537609.aspx? cs-save-lang = 1&cs-lang = vb#code-snippet-1 – HodlDwon

回答

2

是的,你可能想要做在後臺線程的長時間運行的任務。這裏有一個代碼示例,包括如何在完成後將結果返回到UI線程(否則您將收到關於Cross-thread operation not valid的錯誤)。

ThreadPool是一個很好的方式做在後臺線程一些工作。您可以在停止按鈕的按鈕單擊事件中設置stopIt = True

ThreadPool.QueueUserWorkItem(
    Sub() 
    For Each thing In things 
     If stopIt Then Exit Sub 
     'Do the stuff! 
    Next 

    'We're done, update UI 
    Me.UpdateUI("All done!") 
    End Sub) 

要安全地更新UI,您需要確保回到UI線程。

Public Sub UpdateUI(result As String) 
    If Me.InvokeRequired() Then 
    'If we aren't on the UI thread, invoke this function on the UI thread 
    Me.BeginInvoke(Sub() UpdateUI(result)) 
    Exit Sub 
    End If 

    'Update UI here 
    lblResult.Text = result 
End Sub 
+0

請參閱編輯原始問題。我想在你的代碼上寫下你的想法。 – ScotterMonkey

+1

我不熟悉直接使用'Threads',我會說通常人們會推薦再次使用它們。使用'ThreadPool'或'BackgroundWorker'通常會更好。它也取決於'ProcessDo'和'MyInterrupt'在做什麼。如果他們在任何時候更新UI,他們將需要回到UI線程。即使沒有,你可能需要做'Thread.Join'(或類似的東西),當你完成後關閉它們,但是再次......我不熟悉'Thread'。 –

-1

執行是 '停止'(在某種程度上),直到循環完成他的工作,所以是的,你需要多線程。

這是不是一個很長的操作,你需要在循環過程中更新UI控件,那麼你只可以使用Application.DoEvents內循環,以便能夠在應用程序的正常使用其它控制器,FOR循環工作,但我建議你這樣做會對UI性能產生負面影響,但是如果不是一個長時間的循環,那麼你可能會考慮使用DoEvents,而不是引入multi-threading,這只是一種替代方案,不推薦,但是,你可以使用它。

PS:請原諒我的英語

+3

永遠不會使用DoEvents作爲正常程序流程的一部分......永遠不要使用正確的線程。 – HodlDwon

+0

調用此方法會導致在處理所有等待窗口消息時暫停當前線程。如果消息導致事件被觸發,則應用程序代碼的其他區域可能會執行。這可能會導致您的應用程序出現難以調試的意外行爲。如果執行需要很長時間的操作或計算,通常最好在新線程上執行這些操作。有關異步編程的更多信息,請參閱異步編程模型(APM)。 –