2013-10-17 32 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)。 –