我在UI线程中运行了一些方法。在此方法中,将创建一个新线程。我需要UI线程等待,直到这个新线程完成,因为我想等待一些结果才能继续该方法。但我不想让UI冻结,所以同时UI线程正在等待,它也在用UI响应。
以下是我现在所拥有的:
Dim _WaitHandler As New System.Threading.AutoResetEvent(False)
Public Sub Method()
For i As Integer = 0 To 100
Dim myThread As Thread = New Thread(AddressOf ThreadMethod)
myThread.Start()
_WaitHandler.WaitOne()
//next loop or exit?
Next
//this code I want to process after myThread is finished
//but also I don´t want to freeze UI during WaitOne method
End Sub
Private Sub ThreadMethod()
//do something...
_WaitHandler.Set()
End Sub
似乎在WaitOne
方法UI线程休眠时它没有响应,因此UI被冻结。你知道问题在哪里吗?感谢你们。
编辑这是一个忘记写你的事情:myThread创建在for循环中。 myThread完成后,根据myThread的结果,我必须决定是否应继续循环(下一循环)或退出循环。我的代码已经过编辑。
如果我使用BackgroundWorker,UI线程将自动继续下一个循环。
答案 0 :(得分:2)
UI线程不应该等待任何事情。这是一个不好的做法。 使用Background Worker并将适当的侦听器附加到事件DoWork,ProgressChanged,RunWorkerCompleted http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx
答案 1 :(得分:0)
如果您使用ThredSleep
或WaitOne
。它显然会冻结屏幕,因为主UI线程已停止/等待。我建议你使用Tasks并设置一个CallBack,这样后台作业就可以运行而不会冻结UI。因此可以在回调中获得任务结果。
我举个例子:
new TaskFactory().StartNew(BackGroundTask).ContinueWith(TaskCancelationCallBack);
//get the result in a callback
private void TaskCancelationCallBack(System.Threading.Tasks.Task task)
{
//Get Task Result
}
答案 2 :(得分:0)
无论如何,UI几乎总是在等待 - 等待用户输入和其他数据。这是一个状态机,通过消息提供消息。输入队列。你应该这样对待它,并提供线程完成信息作为另一个输入消息。
你不应该试图在GUI事件处理程序中等待,无论它最初看起来多么诱人。
查看Control.BeginInvoke()或Task类。
答案 3 :(得分:0)
这种模式可以做你想做的事情
Public Sub Method()
Dim myThread As Threading.Thread = New Threading.Thread(AddressOf ThreadMethod)
myThread.IsBackground = True
myThread.Start()
End Sub
Private Sub ThreadMethod()
'do something...
AfterThreadMethod()
End Sub
Delegate Sub AfterThreadMethodDel()
Private Sub AfterThreadMethod()
' //this code I want to process after myThread is finished
'if this code must run on the UI then
If Me.InvokeRequired Then
'not on the UI
Dim foo As New AfterThreadMethodDel(AddressOf AfterThreadMethod)
Me.Invoke(foo)
Else
'on the UI
End If
End Sub