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

时间:2015-03-04 13:03:08

标签: .net vb.net awesomium headless-browser

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

我正在使用这个类的问题是,它只适用于第一个实例。后续实例不会导致在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类,这是一个像这样的网络刮刀:

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在直接调用后失败。 I.E.只有Browser类的第一个实例才有效。

2 个答案:

答案 0 :(得分:1)

感谢所有评论过的人。

我相信我终于想出了一个适用于Awesomium.Net的工作线程安全包装类

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

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

将此答案留给有兴趣的人士: - )

干杯!

答案 1 :(得分:0)

问题是您在第二次致电RenderingDone = false之前未设置WebCore.QueueWork(Sub() RenderHTML(URL))