2

我想知道是否有人可以帮助我 - 我已经编写 VB.Net 很长时间了,但很少需要在 ASP.Net 中做很多线程。

我正在尝试使用内存浏览器对网站进行“截图”。然后将这些图像记录在数据库中并写入本地文件系统。

当我在本地服务器上运行它时,一切正常。当我在共享托管环境中运行它时,一切都很好,直到我执行 thread.join,此时目标线程立即终止或卡住(没有从任何一个线程接收到进一步的日志信息)。我附上了下面的日志

还附上了关键代码,但简而言之:

对于每个 url,启动一个新线程并 thread.join 到它。新线程将加载浏览器并开始导航。在返回生成的位图图像(下一步)之前,它会一直等待浏览器加载完成。

在浏览器加载完成时,会触发一个事件。处理程序从浏览器捕获位图图像并将其写入本地。

我做了一些谷歌搜索,但找不到很多相关信息——我发现了常见的共享托管问题,并确保我已经解决了这些问题(例如,允许部分受信任的调用者、签署程序集等......)

如果有关于这个主题的知识的人能很好地为我指出正确的方向,我将不胜感激。

非常感谢

注意:我知道目前它会非常慢,因为它是按顺序处理图像的——但是在我让它在一个线程上工作之前,我没有机会让它在多个线程上工作。

这在很大程度上是从代码示例中拼凑起来的,我什至还没有开始整理/更好地组织它,所以为稍微混乱的代码道歉。

Public Function GetWebsiteImage(ByVal URL As String, Optional ByVal BrowserWidth As Integer = 1280, Optional ByVal BrowserHeight As Integer = 1024) As Bitmap
    LogIt(String.Format("Webshot {1}: {0}", "Getting Image", id))
    _URL = URL
    _BrowserHeight = BrowserHeight
    _BrowserWidth = BrowserWidth

    Dim T As Thread
    T = New Thread(New ThreadStart(AddressOf GenerateImage))

    T.SetApartmentState(ApartmentState.STA)
    'T.IsBackground = True
    LogIt(String.Format("Webshot {1}: {0}", "Starting Thread", id))
    T.Start()

    '*** THIS IS THE LAST LOG ENTRY I SEE ***
    LogIt(String.Format("Webshot {1}: {0}", "Joining Thread", id))
    T.Join()

    Return _Bitmap
End Function

Friend Sub GenerateImage()
    LogIt(String.Format("Webshot {1}: {0}", "Instantiating Web Browser", id))
    Dim _WebBrowser As New WebBrowser()
    _WebBrowser.ScrollBarsEnabled = False
    LogIt(String.Format("Webshot {1}: {0}", "Navigating", id))
    _WebBrowser.Navigate(_URL)
    AddHandler _WebBrowser.DocumentCompleted, AddressOf WebBrowser_DocumentCompleted
    'AddHandler _WebBrowser.
    While _WebBrowser.ReadyState <> WebBrowserReadyState.Complete
        Application.DoEvents()
    End While
    LogIt(String.Format("Webshot {1}: {0}", "Disposing", id))
    _WebBrowser.Dispose()
End Sub

Private Sub WebBrowser_DocumentCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
    LogIt(String.Format("Webshot {1}: {0}", "Document load complete", id))
    Dim _WebBrowser As WebBrowser = DirectCast(sender, WebBrowser)
    _WebBrowser.ClientSize = New Size(Me._BrowserWidth, Me._BrowserHeight)
    _WebBrowser.ScrollBarsEnabled = False
    _Bitmap = New Bitmap(_WebBrowser.Bounds.Width, _WebBrowser.Bounds.Height)
    _WebBrowser.BringToFront()
    _WebBrowser.DrawToBitmap(_Bitmap, _WebBrowser.Bounds)
    _PageTitle = _WebBrowser.DocumentTitle
    LogIt(String.Format("Webshot {1}: {0}", "About to capture bitmap", id))
    _Bitmap = DirectCast(_Bitmap.GetThumbnailImage(_BrowserWidth, _BrowserHeight, Nothing, IntPtr.Zero), Bitmap)
    LogIt(String.Format("Webshot {1}: {0}", "Bitmap captured", id))
End Sub

以及我看到的日志条目:

2010 01 19 02:21:01 > Starting Process
2010 01 19 02:21:01 > Capture 229 Processing: http://www.obfuscated.com/
2010 01 19 02:21:01 > Capture 229 Found capture db record
2010 01 19 02:21:01 > Webshot f7710f41-cac0-4ed1-93df-020620257c91: Instantiated
2010 01 19 02:21:01 > Capture 229 Requesting image
2010 01 19 02:21:01 > Webshot f7710f41-cac0-4ed1-93df-020620257c91: Getting Image
2010 01 19 02:21:01 > Webshot f7710f41-cac0-4ed1-93df-020620257c91: Starting Thread
2010 01 19 02:21:01 > Webshot f7710f41-cac0-4ed1-93df-020620257c91: Joining Thread
4

1 回答 1

1

当您在本地服务器上运行它时,您是指 ASP.NET 个人 Web 服务器还是本地安装的 IIS?前者甚至无法与 IIS 相提并论,因为它作为交互式 Windows 应用程序运行,而使用后者,您将作为没有 UI 的服务运行,并且线程的行为由 IIS 严格控制。

您可以尝试在 Page 指令上设置 aspcompat="true",但很可能托管公司已配置 IIS 工作进程 ping,这将终止在定义的时间段内无响应的线程。

最重要的是,WebBrowser 控件(以及它包装的 SHDocVw ActiveX 控件)并非设计为在非交互式服务进程中工作,并且您可能需要进行艰难的攀登才能使其工作。不幸的是,我不知道任何更安全的选择。

于 2010-01-19T03:42:34.750 回答