我在SO和其他地方看到过几个类似的问题,但似乎都不适合我。
我的项目中有一个小的Window
,其中包含一个LoadingAnimation,我在应用程序启动时会显示它,并希望保持实际处理的运行。这是我的启动代码:
Dim WaitWindow As New WaitWindow("Loading application...")
WaitWindow.Show()
LongRunningLoading()
WaitWindow.Close()
下面是LongRunningLoading()
函数,我试图在一个单独的线程上运行它来避免阻塞我的动画:
Private Function LongRunningLoading() As Boolean
Dim resetEvent As New System.Threading.ManualResetEvent(False)
Dim RetVal As Boolean = False
ThreadPool.QueueUserWorkItem(Sub(state)
'DO SOMETHING AND RETURN RESULTS
resetEvent.Set()
End Sub,
RetVal)
resetEvent.WaitOne()
Return RetVal
End Function
除了不播放加载动画之外,其他一切都按预期进行。我做错了什么?
我做错了什么?
你这样做:
resetEvent.WaitOne()
这会阻塞UI线程。不要那样做。相反,请记住,UI基本上是基于事件的——除非您使用VB11中的异步功能,否则您必须以基于事件的方式编写代码。因此,基本上,当长时间运行的任务完成时,您需要返回到UI线程来执行WaitWindow.Close()
部分。
如果可以使用.NET 4.5和VB 11,则可以使用Task.Run
为长时间运行的工作启动一个新任务,然后使用异步方法启动该任务的Await
。
它们都在UI线程上运行,这就是加载动画等待的原因。尝试将BackgroundWorker用于LongRunningLoading进程,然后在需要时返回UI线程以获得结果。
这种方法对我有效:
Dim waitwindow As New WaitWindow("Loading application...")
ThreadPool.QueueUserWorkItem( _
Sub()
LongRunningLoading()
Dispatcher.Invoke(New Action(AddressOf waitwindow.Close))
End Sub)
waitwindow.ShowDialog()
可以帮助别人。