我正在编写一个库以自动化Internet Explorer。该库通过启动一个线程并使用Dispatcher.Run来设置自己的消息循环。这样做的原因是将Internet Explorer和mshtml保存在同一个线程上。
然后我在库中使用以下内容。
Private ExDispatcher As Dispatcher
Private Success As Boolean
Private EXThreadWaiter As Threading.AutoResetEvent
Public Async Function ClickAndWaitForNewPageAsync() As Task(Of Boolean)
Return Await Task.Run(Of Boolean)(Function()
ExDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, Sub() startClickAndWaitForNewPage())
EXThreadWaiter.WaitOne()
Debug.Print("Completed with: " + Success.ToString)
Return Success
End Function)
End Function
Private Sub startClickAndWaitForNewPage()
'do a lot of stuff and wait for internet explorer
'if we are happy and all good set Success = True
'now let the thread in the task go
EXThreadWaiter.Set()
End Sub
ClickAndWaitForNewPageAsync启动一个新线程上的任务,然后立即使用我的消息循环调用startClickAndWaitForNewPage并完成所有Internet Explorer的工作。当一切正常时,变量Success被设置为一个值,并且调用EXThreadWaiter.Set()来释放任务线程并返回结果。
因此,该库的客户端使用它,如下所示。
Private Async Sub someFunction()
Dim res As Boolean = Await ClickAndWaitForNewPageAsync()
If res Then
'continue on with code
Else
'do nothing
End If
End Sub
我遇到的问题是如何关闭或停止因各种原因需要发生的库。我目前在与ClickAndWaitForNewPageAsync
相同的类中使用此方法Public Sub StopIt()
Success = False
EXThreadWaiter.Set()
End Sub
此方法将Success设置为False并让任务继续。这大部分工作正常,但有可能发生以下情况。
这意味着在someFunction中,它继续使用其代码,认为一切正常,但实际上并非如此。
如何防止这种情况发生?
顺便说一下,我认为取消令牌等不会有所帮助,但我很高兴能听到不同的声音。
我之前使用的 我以前没有使用任务。我只是使用Dispatcher begininvoke,这意味着一切都在正确的线程上完成,客户端必须订阅一个事件,当一切成功完成时将触发。这对我来说是不整洁的,因此我正在尝试这种新方法。