Pergunta

Gostaria de saber se alguém pode me ajudar - estou programando o vb.net há muito tempo, mas raramente tive que fazer muita coisa no ASP.NET.

Estou tentando tirar "capturas de tela" de sites usando um navegador na memória. Essas imagens são então registradas em um banco de dados e escritas no sistema de arquivos local.

Quando eu o executo no meu servidor local, tudo funciona bem. Quando eu o executo em um ambiente de hospedagem compartilhado, tudo está bem até que eu faça um thread.COIN, momento em que o thread de destino termina imediatamente ou fica preso (nenhuma informação adicional de registro é recebida de qualquer thread). Anexei o log abaixo

O código crucial também está anexado, mas em resumo é:

Para cada URL, inicie um novo thread. O novo thread carregará o navegador e começará a navegação. Em seguida, ele será o NOOP até que a carga do navegador tenha sido concluída antes de retornar a imagem do bitmap gerada (próxima etapa).

Na conclusão da carga do navegador, um evento dispara. O manipulador captura a imagem do Bitmap do navegador e a escreve para um local.

Eu fiz um pouco de Google e não consigo encontrar muitas informações relacionadas - encontrei problemas comuns de hospedagem compartilhada e garanti que eu os cobertos (por exemplo, permitindo chamadores parcialmente confiáveis, assembléias de assinatura, etc ...)

Eu apreciaria se alguém com conhecimento sobre esse tópico teria a gentileza de me apontar na direção certa.

Muito Obrigado

NB: Estou ciente de que, atualmente, será muito lento, pois está processando imagens sequencialmente - mas até que eu possa fazer com que funcione em um tópico, não tenho chance de fazê -lo trabalhar em vários threads.

Isso é amplamente mutilado de amostras de código e eu nem comecei a arrumar / organizá -lo melhor, então desculpas pelo código um pouco confuso.

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

E as entradas de log que vejo:

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
Foi útil?

Solução

Quando você o está executando no servidor local, você quer dizer o servidor pessoal do ASP.NET ou uma instalação local do IIS? O primeiro nem é comparável ao IIS, porque é executado como um aplicativo interativo do Windows, enquanto com o último você estará executando como um serviço que não pode ter interface do usuário e o comportamento dos threads é governado estritamente pelo IIS.

Você pode tentar definir aspcompat = "true" na diretiva da página, mas mais provável do que não, a empresa de hospedagem configurou o Pinging do Processo do Trabalhador do IIS, que encerrará os threads que não respondem por um período de tempo definido.

O ponto principal é que o controle do WebBrowser (e o controle ActiveX Shdocvw que ele envolve) não foi projetado para funcionar em um processo de serviço não interativo e provavelmente você está em uma subida difícil tentando fazê-lo funcionar. Infelizmente, não conheço nenhuma alternativa mais segura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top