【发布时间】:2018-06-28 15:07:09
【问题描述】:
当长时间运行的操作运行时,我的 Winforms 应用程序在图片框内显示动画 gif。但是,它在等待任务完成时冻结:
Public Class MyUserControl
Sub Initialize()
Dim folderscantask = Task.Factory.StartNew(
Function() EwsManagedApiScanFolderHierarchy(),
TaskCreationOptions.LongRunning
)
folderdictask.Wait()
Dim folderscanresult = folderscantask.Result
End Sub
Function EwsManagedApiScanFolderHierarchy() As Dictionary(Of String, String)
'Performs a long, recursive operation involving a
'Microsoft.Exchange.WebServices.Data.ExchangeService object
End Function
End Class
为了保持 PictureBox 的动画运行,我应该做些什么不同的事情?
编辑
这是对我的问题的更完整描述,这次我使用了 Async/Await(因为我被告知 Task.Wait() 会阻塞调用者线程)。现在,动画移动正常,直到它第一次到达MyUserControl.BuildFolderMenus(),然后冻结。这是不可避免的吗?我的意思是,动画不是在专用线程中运行吗?
Public Class MyForm : Inherits Form
'Form has a PictureBox named PictureBoxWaiting that shows an animated gif
Public Async Sub MyButton_Click(sender as Object, e as EventArgs) Handles MyButton.Click
PictureBoxWaiting.Show()
PictureBoxWaiting.BringToFront()
Await MyUserControl1.Initialize()
PictureBoxWaiting.Hide()
MyUserControl1.Show()
End Sub
End Class
Public Class MyUserControl
Public Async Function Initialize() As Task
Dim folderdic = Await GetFolderHierarchyAsync()
BuildFolderMenus(ToolStripDropDownButtonFolders, folderdic)
End Function
Public Async Function GetFolderHierarchyAsync() As Task(Of Dictionary(Of String, String))
Return Await Task.Factory.StartNew(
Function() EwsManagedApiScanFolderHierarchy(),
TaskCreationOptions.LongRunning
)
End Function
Function EwsManagedApiScanFolderHierarchy() As Dictionary(Of String, String)
'Performs a long, recursive operation involving a
'Microsoft.Exchange.WebServices.Data.ExchangeService object
End Function
Private Sub BuildFolderMenus(menu As ToolStripDropDownItem, dic As Dictionary(Of String, String))
'This reads the dictionary containing the folder hierarchy
'and recursively adds menu items in order that folders´
'subfolders correspond to subitems inside an item
'
'This must run in UI thread since it creates UI controls
End Sub
End Class
【问题讨论】:
-
您对
folderdictask.Wait()的调用将阻塞当前线程,直到任务完成,因此您并没有完全异步运行它。查看async/await。 -
Async/Await 是我的第一种方法,但是在扫描文件夹层次结构并将相应的菜单项添加到 ui 之前,它会使运行流过早地从该方法返回
-
那么有些事情你做得不太正确,但如果你想在特定线路等待任务,你必须使用它。当然,在当前状态下,您也可以切换回旧的
ContinueWith()方法。 -
我认为你应该更关注为什么你的 async/await 方法不起作用,而不是尝试修复你当前的代码,因为 async/await 是一种执行异步工作的非常简单而强大的方法。也许递归是问题的一部分?
-
不要为反对票出汗——我会说这是个人话题