2

誰かが私を助けることができるかどうか疑問に思います - 私は長い間 VB.Net をプログラミングしてきましたが、ASP.Net で多くのスレッドを実行する必要はめったにありませんでした。

インメモリ ブラウザを使用して Web サイトの「スクリーンショット」を取得しようとしています。これらのイメージは DB に記録され、ローカル ファイル システムに書き込まれます。

ローカルサーバーで実行すると、すべて正常に動作します。共有ホスティング環境で実行すると、thread.join を実行するまでは問題ありません。その時点で、ターゲット スレッドがすぐに終了するかスタックします (どちらのスレッドからもログ情報が受信されません)。以下にログを添付しました

重要なコードも添付されていますが、要するに次のとおりです。

各 URL に対して、新しいスレッドを開始し、それに thread.join します。新しいスレッドがブラウザをロードし、ナビゲーションを開始します。生成されたビットマップ画像を返す前に、ブラウザのロードが完了するまでヌープします (次のステップ)。

ブラウザーの読み込みが完了すると、イベントが発生します。ハンドラーは、ブラウザーからビットマップ イメージをキャプチャし、ローカルに書き込みます。

いくつかのグーグル検索を行ったが、多くの関連情報を見つけることができない - 一般的な共有ホスティングの問題を発見し、それらをカバーしていることを確認した (例えば、部分的に信頼された呼び出し元を許可する、アセンブリに署名するなど...)

このトピックに関する知識を持っている人が親切に私を正しい方向に向けてくれれば幸いです.

どうもありがとう

注意: 画像を順次処理しているため、現時点では非常に遅くなることは承知していますが、1 つのスレッドで動作するようになるまでは、複数のスレッドで動作する可能性はありません。

これは大部分がコード サンプルからまとめられたものであり、私はそれを整理/整理することさえ始めていないので、少し乱雑なコードをお詫びします。

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 のローカル インストールを意味しますか? 前者はインタラクティブな Windows アプリケーションとして実行されるため、IIS と比較することさえできませんが、後者では UI を持たないサービスとして実行され、スレッドの動作は IIS によって厳密に管理されます。

Page ディレクティブで aspcompat="true" を設定することもできますが、多くの場合、ホスティング会社は IIS ワーカー プロセスの ping を構成しており、定義された期間応答しないスレッドを終了させます。

要するに、WebBrowser コントロール (およびそれがラップする SHDocVw ActiveX コントロール) は、非対話型サービス プロセスで動作するように設計されていないため、それを機能させようとすると、困難を極める可能性があります。残念ながら、より安全な代替手段については知りません。

于 2010-01-19T03:42:34.750 に答える