Thread.Join в среде общего хостинга
Интересно, может ли кто-нибудь мне помочь - я давно программирую на VB.Net, но мне редко приходилось делать много потоков в ASP.Net.
Я пытаюсь сделать "скриншоты" сайтов с помощью браузера в памяти. Эти образы затем записываются в БД и записываются в локальную файловую систему.
Когда я запускаю его на локальном сервере, все работает нормально. Когда я запускаю его в среде общего хостинга, все нормально, пока я не выполню thread.join, и в этот момент целевой поток либо немедленно завершается, либо застревает (дальнейшая информация о регистрации не поступает ни от одного потока). Я прикрепил журнал ниже
Ключевой код также прилагается, но вкратце:
Для каждого URL создайте новый поток и присоединитесь к нему. Новый поток загрузит браузер и начнет навигацию. затем он будет работать до тех пор, пока загрузка браузера не завершится, а затем будет возвращено созданное растровое изображение (следующий шаг).
По завершении загрузки браузера происходит событие. Обработчик захватывает растровое изображение из браузера и записывает его в локальный.
Я немного погуглил и не могу найти много сопутствующей информации - я обнаружил общие проблемы с общим хостингом и убедился, что мне их удалось решить (например, разрешить вызывающим частичные вызовы, подписать сборки и т. Д.)
Я был бы признателен, если бы кто-нибудь, обладающий знаниями по этой теме, был бы достаточно любезен, чтобы указать мне правильное направление.
Большое спасибо
NB: я знаю, что в настоящее время он будет очень медленным, поскольку он обрабатывает изображения последовательно - но пока я не смогу заставить его работать в одном потоке, у меня нет шансов заставить его работать в нескольких потоках.
Это в значительной степени искажено из примеров кода, и я даже не начал приводить его в порядок / организовывать лучше, поэтому извиняюсь за немного грязный код.
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
1 ответ
Когда вы запускаете его на локальном сервере, вы имеете в виду персональный веб-сервер ASP.NET или локальную установку IIS? Первый даже не сравним с IIS, потому что он работает как интерактивное приложение Windows, тогда как с последним вы будете работать как сервис, который не может иметь пользовательского интерфейса, а поведение потоков строго регулируется IIS.
Вы можете попробовать установить aspcompat="true" в директиве Page, но, скорее всего, хостинговая компания настроила проверку связи с рабочим процессом IIS, которая прервет потоки, которые не отвечают в течение определенного периода времени.
Суть в том, что элемент управления WebBrowser (и элемент управления SHDocVw ActiveX, который он переносит) не предназначен для работы в неинтерактивном сервисном процессе, и вы, вероятно, столкнетесь с трудностями, пытаясь заставить его работать. К сожалению, я не знаю ни одной более безопасной альтернативы.