2013-07-16 124 views
0

我已阅读关于此的其他帖子,但我似乎仍然无法让它正常工作。BackgroundWorker冻结图形用户界面

每当我的BackgroundWorker开始工作,我的函数API.CheckForUpdate导致GUI挂起。我无法点击任何东西。它只会冻结半秒钟,但足以注意到。

我该如何解决这个问题?我是否应该深入探讨API.CheckForUpdate并在特定语句上运行单个线程,或者我可以只有一个全包线程来处理这个问题? API.CheckForUpdate不引用Form1中的任何内容。

此外,我认为Form1_Load不是放置RunWorkerAsync调用的最佳位置。哪里更好?

'Declarations 
Dim ApplicationUpdate As BackgroundWorker = New BackgroundWorker 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    ApplicationUpdate.WorkerSupportsCancellation = True 
    ApplicationUpdate.WorkerReportsProgress = True 
    AddHandler ApplicationUpdate.DoWork, AddressOf ApplicationUpdate_DoWork 
    AddHandler ApplicationUpdate.ProgressChanged, AddressOf ApplicationUpdate_ProgressChanged 
    AddHandler ApplicationUpdate.RunWorkerCompleted, AddressOf ApplicationUpdate_RunWorkerCompleted 
    ApplicationUpdate.RunWorkerAsync() 
End Sub 

Private Sub ApplicationUpdate_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) 
    'Check for an update (get the latest version) 
    Dim LatestVersion = API.CheckForUpdate 
End Sub 

Private Sub ApplicationUpdate_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) 
    'Nothing here 
End Sub 

Private Sub ApplicationUpdate_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) 
    'Work completed 
    MsgBox("Done") 
End Sub 
+0

你可以发布CheckForUpdates方法吗? – OneFineDay

+1

我可以,但它很长。基本上,它创建一个WebRequest来使用GET请求查询网站,并使用StreamReader将其读入内存。例如,该网站只包含一个版本号 - 2.4。 – Brady

回答

0

尝试在Load事件之外启动该过程。创建一个定时器并启动它的Load事件,然后办理蜱事件:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick 
    Timer1.Enabled = False 
    ApplicationUpdate.RunWorkerAsync() 
End Sub 
+0

谢谢,但我试过了,它仍然冻结。我将计时器设置为1秒钟的Form1控件。 – Brady

1

它不是一个背景工人修复,但如果你不介意的走动,并没有找到答案,你可以代码是这样的:

请记住,当你第一次启动一个线程,并且你正在编码模型时,你必须将(me)传递给初始线程,因为VB有一个“默认表单实例”的概念。对于应用程序名称空间中的每个表单,将在Forms属性下的My名称空间中创建一个默认实例。

而这仅仅是增加一个额外的参数,像这样

---------------------- /启动主线程/ --- --------------------------------

Private Sub FindCustomerLocation() 
Dim Findcontractor_Thread As New Thread(AddressOf **FindContractor_ThreadExecute**) 
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal 
Findcontractor_Thread.Start(me) 
End Sub 

----------- ------- /运行的线程/ ---------------

Private Sub **FindContractor_ThreadExecute**(beginform as *NameOfFormComingFrom*) 
Dim threadControls(1) As Object 
threadControls(0) = Me.XamDataGrid1 
threadControls(1) = Me.WebBrowserMap 

**FindContractor_WorkingThread**(threadControls,beginform) ' ANY UI Calls back to the Main UI Thread MUST be delegated and Invoked 
End Sub 

--------- --------- /如何设置UI从一个线程调用/ ---------------------

Delegate Sub **FindContractor_WorkingThread**(s As Integer,beginform as  *NameOfFormComingFrom*) 
Sub **FindContractor_WorkingThreadInvoke**(ByVal s As Integer,beginform as  *NameOfFormComingFrom*) 
If beginform.mouse.InvokeRequired Then 
Dim d As New FindContractor_WorkingThread(AddressOf  FindContractor_WorkingThreadInvoke) 
beginform.Invoke(d, New Object() {s,beginform}) 
Else 
beginform.Mouse.OverrideCursor = Cursors.Wait 

'Do something... 

beginform.Mouse.OverrideCursor = Nothing 
End If 
End Sub 

Sources From Pakks Answer Tested!