我试图对我的函数进行编程,因此我的应用程序的主GUI在任务运行时无法响应。
目前我的form1.vb是这样的。我已将其剪下来以减少文字,但一切正常:
Public Class MAIR
Private Sub InstallTheAgent_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InstallTheAgent.Click
InstallAgentWorker.RunWorkerAsync()
End Sub
Private Sub InstallAgentWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles InstallAgentWorker.DoWork
'Do some stuff
End Sub
Private Sub InstallAgentWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles InstallAgentWorker.RunWorkerCompleted
' Called when the BackgroundWorker is completed.
MsgBox("Installation of the Agent Complete")
ProgressBar1.Value = 0
End Sub
End Class
从我的理解,当按钮"打开"按下它,它调用函数Install,它应该在一个单独的线程中启动它,但这不起作用。
这似乎有效,但GUI仍然锁定,表明它不在单独的线程中
答案 0 :(得分:2)
我建议使用BackgroundWorker Class来实现这种基本线程。你没有太多进展,所以基本的实现应该足够了。这是我将如何去做的片段。我的方法有点过于复杂(我将基类和事件连接起来以捕获大量的工作事件)在这里简洁地列出,所以我将缩写。
Public Class MAIR
Dim worker as BackgroundWorker
Private Sub Open_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Open.Click
worker.RunWorkerAsync()
End Sub
Protected Sub Worker_DoWork(ByVal sender as Object, ByVal e as DoWorkEventArgs)
Call Shell("psexec.exe", AppWinStyle.Hide, True)
End Sub
Protected Sub Worker_ProgressChanged(Byval sender as Object, ByVal e as ProgressChangedEventArgs)
' You can track progress reports here if you use them
End Sub
Protected Sub Worker_RunWorkerCompleted(Byval sender as Object, ByVal e as RunWorkerCompletedEventArgs)
' Report back to the main application that the thread is completed
End Sub
Private Sub Install_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
worker = New BackgroundWorker()
' Add the event wire-ups
' ### This event wire-up establishes the link
' ### that is used by RunWorkerAsync to initiate
' ### the code you want to run asynchronously
AddHandler worker.DoWork, AddressOf Worker_DoWork
AddHandler worker.ProgressChanged, AddressOf Worker_ProgressChanged
AddHandler worker.RunWorkerCompleted, AddressOf Worker_RunWorkerCompleted
End Sub
End Class
这全部都是从C#翻译过来的,所以请把它当作伪代码。重要的部分是BackgroundWorker及其行为的文档。这个类中有很多非常棒的功能可以解决线程的麻烦,以便进行简单的使用。此课程位于System.ComponentModel
,因此您需要参考和Imports
声明。
编辑:我忘了提到的一点是,一旦工作人员被异步解雇,跟踪它或与主应用程序通信的唯一方式是通过ProgressChanged
和{{1事件。没有全局变量或跨线程项可用,因此您必须使用内置属性传入运行期间可能需要的任何值(例如,计算机名称)。