Awesomium.Net 用于多线程访问的包装器 class 只工作一次

Awesomium.Net wrapper class for multi-threaded access only works once

要测试此 class 请从 here 安装 Awesomium.Net sdk 并将对 Awesomium.Core.dll 的引用添加到 visual studio 项目。

我遇到的问题 class 是,它只适用于第一个实例。随后的实例不会导致在 WebView 对象上触发适当的事件,并且在以后的实例中不会返回任何结果。我已经为此苦苦挣扎了好几天,似乎无法弄清楚为什么它只能工作一次。请帮忙...

Imports Awesomium.Core

Public Class Browser

    Private Shared Thread As Threading.Thread
    Private Shared CoreIsRunning As Boolean = False
    Dim RenderedHTML As String = ""
    Dim RenderingDone As Boolean = False

    Private Shared Sub AwesomiumThread()
        WebCore.Initialize(New WebConfig With {.LogLevel = LogLevel.None}, False)
        WebCore.Run(Sub(s, e)
                        CoreIsRunning = True
                    End Sub)
    End Sub

    Shared Sub DeInit()
        WebCore.Shutdown()
        Thread = Nothing
    End Sub

    Shared Sub Init()
        If Not WebCore.IsInitialized And IsNothing(Thread) Then
            Thread = New Threading.Thread(AddressOf AwesomiumThread)
            Thread.Start()
        End If
    End Sub

    Sub New()
        Init()
    End Sub

    Function GetRenderedHTML(URL As String) As String
        Do Until CoreIsRunning
            Task.Delay(300).Wait()
        Loop

        WebCore.QueueWork(Sub() RenderHTML(URL))

        Dim startTime As Date = Date.UtcNow
        Do Until RenderingDone = True
            If Date.UtcNow.Subtract(startTime).TotalSeconds >= 30 Then
                'view.Dispose()
                'view = Nothing
                'session.Dispose()
                'session = Nothing
                Exit Do
            End If
            Task.Delay(1000).Wait()
        Loop

        If String.IsNullOrEmpty(RenderedHTML) Then
            Throw New Exception("Rendering failed!")
        End If

        Return Me.RenderedHTML
    End Function

    Private Sub RenderHTML(URL As String)
        Dim session As WebSession = WebCore.CreateWebSession(New WebPreferences With {.LoadImagesAutomatically = False, .LocalStorage = False, .Plugins = False, .RemoteFonts = False, .WebAudio = False, .CanScriptsOpenWindows = False, .DefaultEncoding = "utf-8"})
        Dim view As WebView = WebCore.CreateWebView(1100, 600, session, WebViewType.Offscreen)
        RenderingDone = False
        AddHandler view.LoadingFrameComplete, Sub(s, e)
                                                  If e.IsMainFrame Then
                                                      Me.RenderedHTML = view.ExecuteJavascriptWithResult("document.documentElement.outerHTML").ToString
                                                      RenderingDone = True
                                                      RemoveHandler view.LoadingFrameFailed, Nothing
                                                      view.Dispose()
                                                      view = Nothing
                                                      session.Dispose()
                                                      session = Nothing
                                                  End If
                                              End Sub
        AddHandler view.LoadingFrameFailed, Sub(s, e)
                                                If e.IsMainFrame Then
                                                    Me.RenderedHTML = ""
                                                    RenderingDone = True
                                                    RemoveHandler view.LoadingFrameFailed, Nothing
                                                    view.Dispose()
                                                    view = Nothing
                                                    session.Dispose()
                                                    session = Nothing
                                                End If
                                            End Sub
        view.Source = URL.ToUri
    End Sub

End Class

我在多线程 winforms 应用程序中使用上面的 Browser class,它是一个网络抓取工具,如下所示:

Dim A as New Browser
Dim ResultA As String = A.GetRenderedHTML("http://google.com")

Dim B as New Browser
Dim ResultB As String = B.GetRenderedHTML("http://google.com")

A.GetRenderedHTML 有效,但 B.GetRenderedHTML 在之后直接调用时失败。 IE。只有 Browser class 的第一个实例有效。

问题是你在第二次调用WebCore.QueueWork(Sub() RenderHTML(URL))之前没有设置RenderingDone = false

感谢所有评论的人。

我相信我终于想出了一个适用于 Awesomium.Net

的线程安全包装器 class

我已经在 github 上发布了最终的工作源代码。您可以在下面的 link 查看:

https://github.com/dj-nitehawk/ThreadSafeAwesomium.Net/blob/master/Browser.vb

在这里为感兴趣的人留下这个答案:-)

干杯!