调度程序,任务和取消问题

时间:2017-02-02 06:52:33

标签: vb.net multithreading

我正在编写一个库以自动化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并让任务继续。这大部分工作正常,但有可能发生以下情况。

  1. startClickAndWaitForNewPage将Success设置为True
  2. 调用EXThreadWaiter.Set()
  3. Debug.Print(“Completed with:”+ Success.ToString)表示Success为True
  4. StopIt()运行设置Success = False
  5. 客户端代码中的someFunction接收Success = True
  6. 这意味着在someFunction中,它继续使用其代码,认为一切正常,但实际上并非如此。

    如何防止这种情况发生?

    顺便说一下,我认为取消令牌等不会有所帮助,但我很高兴能听到不同的声音。

    我之前使用的 我以前没有使用任务。我只是使用Dispatcher begininvoke,这意味着一切都在正确的线程上完成,客户端必须订阅一个事件,当一切成功完成时将触发。这对我来说是不整洁的,因此我正在尝试这种新方法。

0 个答案:

没有答案