异步函数与对话框
首先我们定义一个用于选择文件的自定义函数OpenFile:
Dim
dlg
As
New
OpenFileDialog()
dlg.Filter =
"Excel文件|*.xls|Word文件|*.doc|Access文件|*.mdb"
If
dlg.ShowDialog() = DialogResult.Ok
Then
Return dlg.FileName
End
If
然后在命令窗口测试:
'''Async
Dim
file
As
String
=
Await
Functions.ExecuteAsync("OpenFile")
Return
file
测试代码不会有任何反应,极端情况下可能会导致程序崩溃,这是因为异步函数在独立的线程执行,也就是在非UI线程执行导致的,因此无法直接操作或显示UI元素
为此Foxtable提供了6个专门用于异步函数的对话框:
MessageBoxA
FontDialogA
ColorDialogA
OpenFileDialogA
SaveFileDialogA
FolderBrowserDialogA
这些对话框和之前的对话框相比,只是名称加上了后缀"A",表示用于异步函数,用法则完全一样。
现在新建一个OpenFileAsync 函数,代码设置为:
'''Async
Dim
dlg
As
New
OpenFileDialogA()
dlg.Filter =
"Excel文件|*.xls|Word文件|*.doc|Access文件|*.mdb"
If
Await
dlg.ShowDialog() = DialogResult.Ok
Then
Return
dlg.FileName
End
If
现在在命令窗口执行下面的测试代码,则一切正常:
'''Async
Dim
file
As
String
=
Await
Functions.ExecuteAsync("OpenFileAsync")
Return
file
如果不需要等待,或不需要获得异步对话框的返回值,则可以不用Await,例如在命令窗口执行:
'''Async
If
Await
MessageBoxA.Show("Foxtable很强大,你同意吗?"
,
"提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) =
DialogResult.Yes
Then
MessageBoxA.Show("很开心,谢谢您的认同!")
'没有用Await
,所以不用等关闭对话框,后面的代码会继续执行:
Output.Show("今天是个好日子!")
Else
Await
MessageBoxA.Show("看来我们还需要努力")
'用了Await
,要等关闭对话框,后面的代码才能继续执行
Output.Show("心想的事儿都能成!")
End
If
可测试两次,分别单击是和否,可以看到内容输出的时机是不同的。
虽然异步对话框是专门为异步函数设计的,但是也可以用在其他地方,只是完全没有必要哈。
为什么提供异步对话框?
常规开发的时候,异步对话框并不是必须的,因为多数时候我们都是在同步代码(包括事件代码以及普通函数)中调用异步函数,完全可以在同步代码中处理UI,然后将高负荷的工作交给异步函数完成,例如:
'''Async
Dim
dlg
As
New
OpenFileDialog()
dlg.Filter =
"Excel文件|*.xls|Word文件|*.doc|Access文件|*.mdb"
If
dlg.ShowDialog() = DialogResult.Ok
Then
Await
Functions.ExecuteAsync("异步函数名",
dlg.FileName)
'
用异步函数处理高负荷任务
End
If
这是最合理也是最方便的方式。
但有时任务比较复杂,同步代码和异步代码交织在一起,可能就需要多个异步函数协同才能完成任务了。
如果你不想将代码分开在两个或多个位置,想在同一个异步函数中完成UI和高负荷的工作,那么异步对话框就排上用场了。
此外如果有用WebViewer开发本地Web应用,因为前端JS调用Foxtable原生代码时,不可以长时间阻塞进程,此时异步对话框是唯一的解决方案。