Я разработал приложение для подсчета очков в реальном времени, основанное на методе длительного опроса, или Comet, как они его еще называют. Я использовал ASP.NET 4.0, работающий на IIS 6 (Windows 2003 - только два процессора, что мне не очень помогает с доступностью потоков в пуле).
Данные поступают в виде .csv
файлов, которые вставляются в исходную папку на веб-сервере, которые я затем импортирую с помощью Microsoft JET 4.0 OleDb Provider и отображаю с использованием различных методов, в зависимости от части приложения. .
Механизм длинного опроса полагается на IHttpAsyncHandler.
. Поскольку это приложение для оценки в реальном времени, пользователь посещает веб-сайт, получает регулярный ответ с текущими данными и при загрузке тела отправляет новый запрос через jquery ajax асинхронному обработчику http.
Затем этот обработчик сохраняет запрос в очереди и возвращает (обычно) поток обратно в пул потоков. Как только это произойдет, я создаю событие ручного сброса и задерживаю операцию, пока создается объект-наблюдатель файловой системы, который отправляется для поиска изменений в папке источника данных csv.
Как только он запускает событие onChange
, я устанавливаю событие ручного сброса, и асинхронной операции разрешается возобновить с получением новых, обновленных файлов csv и ответом клиенту свежими данными.
Все было бы хорошо, если бы я не получал ошибки все время. В общем, очень-очень общий способ, приложение работает, но у меня есть проблема, которую я не могу точно определить.
А именно, я не уверен, связана ли проблема с доступом к файлам CSV, поскольку они могут быть заблокированы процессом, который переносит их на сервер (передача по ftp со спортивного объекта). Или, может быть, я (а) использую IHttpAsyncHandler
, или, может быть, просто у меня недостаточно процессоров и потоков (во что мне трудно поверить, так как у меня только около 3000 уникальных посетителей каждый день. не знаю час за часом числа).
Возможно ли, что IIS 6 windows 2003 с двумя процессорами не сможет поддерживать такого рода приложения?
вот ошибки, которые я получаю:
Тип события: ошибка Источник события: ASP.NET 4.0.30319.0 Категория события: нет КОД события: 1325 Дата: 20.04.2011 Время: 15:33:14 Пользователь: н / д Компьютер: xxx Описание: возникло необработанное исключение и процесс был прекращен.
Идентификатор приложения: / LM / W3SVC / 1 / ROOT Идентификатор процесса: 5264 Исключение: System.Data.OleDb.OleDbException Сообщение: неопределенная ошибка
StackTrace: в System.Data.OleDb.OleDbConnectionInternal..ctor (константа OleDbConnectionString, соединение OleDbConnection)
в System.Data.OleDb.OleDbConnectionFactory.CreateConnection (параметры DbConnectionOptions, PoolGroupConnectionOptions, PoolGroupConnectionInternal, DbConnectionOptions, PoolGroupConnectionInternal), ObjectProviderInfo .ProviderBase.DbConnectionFactory.CreateNonPooledConnection (DbConnection owningConnection, DbConnectionPoolGroup poolGroup) в System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection owningConnection.OutConnectionDbConnectionFactory.GetConnection (DbConnection owningConnection). .OleDbConnection.Open () в Broker.brCSV.readCSV (String fileName) в SwatchTiming.AsynchOperation.StartAsyncTask (Object workItemState) в System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (Состояние объекта) в System. unTryCode (объект userData) в System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup (код TryCode, код очистки BackoutCode, объект userData) в System.Threading.ExecutionContext.RunInternal (контекст выполнения System.Threading.ExecutionContext. Выполнить (ExecutionContext executionContext, обратного вызова ContextCallback, состояние объекта, логическое значение ignoreSyncCtx) в System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () в System.Threading.ThreadPool.ThreadCoolback () в System.Threading.ThreadPool.Threada
А также:
Тип события: ошибка Источник события: создание отчетов об ошибках .NET Runtime 4.0 Категория события: нет КОД события: 5000 Дата: 20.04.2011 Время: 15:33:14 Пользователь: N / AC Компьютер: xxx Описание: EventType clr20r3, P1 w3wp. exe, P2 6.0.3790.3959, P3 45d6968e, P4 system.data, P5 4.0.0.0, P6 4ba1e064, P7 1ea3, P8 87, P9 system.data.oledb.oledbexception, P10 NIL. Дополнительную информацию см. В центре справки и поддержки по адресу http://go.microsoft.com/fwlink/events.asp.Data:0000: 63 00 6c 00 72 00 32 00
clr2.0008: 30 00 72 00 33 00 2c 00 0.r.3.,. 0010: 20 00 77 00 33 00 77 00 .w.3.w.0018: 70 00 2e 00 65 00 78 00
p ... ex0020: 65 00 2c 00 20 00 36 00 e.,. .6.0028: 2e 00 30 00 2e 00 33 00 ..0 ... 3.0030: 37 00 39 00 30 00 2e 00 7.9.0 ... 0038: 33 00 39 00 35 00 39 00 3.9.5.9.0040: 2c 00 20 00 34 00 35 00,. .4.5.0048: 64 00 36 00 39 00 36 00 d.6.9.6.0050: 38 00 65 00 2c 00 20 00 8.e.,. .0058: 73 00 79 00 73 00 74 00 syst0060: 65 00 6d 00 2e 00 64 00 em..d.0068: 61 00 74 00 61 00 2c 00 ata, .0070: 20 00 34 00 2e 00 30 00 .4 ... 0.0078: 2e 00 30 00 2e 00 30 00
..0 ... 0.0080: 2c 00 20 00 34 00 62 00,. .4.b.0088: 61 00 31 00 65 00 30 00 a.1.e.0.0090: 36 00 34 00 2c 00 20 00 6.4.,. .0098: 31 00 65 00 61 00 33 00 1.e.a. 3.00a0: 2c 00 20 00 38 00 37 00,. .8.7.00a8: 2c 00 20 00 73 00 79 00,. .sy00b0: 73 00 74 00 65 00 6d 00 stem00b8: 2e 00 64 00 61 00 74 00 ..dat00c0: 61 00 2e 00 6f 00 6c 00 a ... ol00c8: 65 00 64 00 62 00 2e 00 edb..00d0: 6f 00 6c 00 65 00 64 00 oled00d8: 62 00 65 00 78 00 63 00 bexc00e0: 65 00 70 00 74 00 69 00 epti00e8: 6f 00 6e 00 20 00 4e 00 on .N.00f0: 49 00 4c 00 0d 00 0a 00 I.L .....
и...
Тип события: ошибка Источник события: среда выполнения .NET Категория события: нет КОД события: 1026 Дата: 20.04.2011 Время: 15:34:26 Пользователь: нет Компьютер: xxx Описание: Приложение: w3wp.exe Версия платформы: v4.0.30319 Описание: Процесс был прерван из-за необработанного исключения. Информация об исключении: System.Data.OleDb.OleDbException
Стек: в System.Data.ProviderBase.DbConnectionClosed.OpenConnection (System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory) в System.Data.OleDb.OleDbConnection.Open () в Broker.brCSV.readCSV (System. String) в [ProjectNamespace] .AsynchOperation.StartAsyncTask (System.Object) в System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object) в System.Threading.ExecutionContext.runTryCode (System.Runperstime). ExecuteCodeWithGuaranteedCleanup (TryCode, CleanupCode, System.Object) в System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) в System.Threading.ContextCallback, System.Object) в System.Exreading.ExecutionContext.Response. System.Threading.ContextCallback, System.Object, Boolean) в System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () в System. Threading.ThreadPoolWorkQueue.Dispatch () в System.Threading._ThreadPoolWaitCallback.PerformWaitCallback ()
Еще несколько инфо в конце. Я пытался настроить IIS 6, но это не помогло.
Кто-нибудь знает, что, черт возьми, происходит и почему мой сайт вылетает каждые пять минут?
РЕДАКТИРОВАТЬ: вот мой код в обработчике, надеюсь, это поможет
BeginProcessRequest
выглядит следующим образом (кроме этого я только устанавливаю IsReusable
на false):
Public Function BeginProcessRequest( _
ByVal context As System.Web.HttpContext, _
ByVal cb As System.AsyncCallback, _
ByVal extraData As Object) _
As System.IAsyncResult _
Implements System.Web.IHttpAsyncHandler.BeginProcessRequest
Dim asynch As New AsynchOperation(cb, context, extraData)
asynch.StartAsyncWork()
Return asynch
End Function
а затем класс AsynchOperation
, реализующий IAsyncResult
:
Class AsynchOperation
Implements IAsyncResult
Private _completed As Boolean
Private _state As [Object]
Private _callback As AsyncCallback
Private _context As HttpContext
Private mre As New ManualResetEvent(False)
Dim br As New Broker.brCSV
Dim brLiveGames As New Broker.brLiveGames
ReadOnly Property IsCompleted() As Boolean _
Implements IAsyncResult.IsCompleted
Get
Return _completed
End Get
End Property
ReadOnly Property AsyncWaitHandle() As WaitHandle _
Implements IAsyncResult.AsyncWaitHandle
Get
Return Nothing
End Get
End Property
ReadOnly Property AsyncState() As [Object] _
Implements IAsyncResult.AsyncState
Get
Return _state
End Get
End Property
ReadOnly Property CompletedSynchronously() As Boolean _
Implements IAsyncResult.CompletedSynchronously
Get
Return False
End Get
End Property
Public Sub New(ByVal callback As AsyncCallback, _
ByVal context As HttpContext, _
ByVal state As [Object])
_callback = callback
_context = context
_state = state
_completed = False
End Sub
Public Sub StartAsyncWork()
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartAsyncTask), Nothing)
End Sub
Private Sub StartAsyncTask(ByVal workItemState As [Object])
Dim fsw As New FileSystemWatcher("D:\ClientRoot\Swatchtiming\bv\ReadData\")
fsw.NotifyFilter = NotifyFilters.LastWrite
AddHandler fsw.Changed, AddressOf OnChanged
fsw.EnableRaisingEvents = True
fsw.IncludeSubdirectories = False
Dim aTimer As New System.Timers.Timer
AddHandler aTimer.Elapsed, AddressOf OnTimerChanged
aTimer.Interval = 60000
aTimer.Enabled = True
mre.WaitOne()
Dim rdr As OleDbDataReader
Dim i As Integer = 0
Dim eventName As String = ""
Dim dsFiles As DataSet = brLiveGames.getFileNameWithEventTitle()
Dim teamClass As String = "TeamA"
Dim serveIndicator As String = ""
Dim serveImage As String = ""
Dim serveSpeed As String = ""
Dim fileName As String = ""
Dim fileNumber As String = ""
Dim matchID As String = ""
Dim venueLocation As String = ""
Dim set1, set2, set3 As String
For i = 0 To Convert.ToInt16(dsFiles.Tables(0).Rows.Count) - 1
If eventName <> dsFiles.Tables(0).Rows(i).Item("EventTitle") Then
eventName = dsFiles.Tables(0).Rows(i).Item("EventTitle")
_context.Response.Write("<div class='eventTitle'>" & eventName.ToString() & " <span class='bracketLink'>- <a href='Brackets.aspx?Brackets=" & dsFiles.Tables(0).Rows(0).Item("BracketsFile") & "'>View brackets</a></span></div>")
End If
rdr = br.readCSV(dsFiles.Tables(0).Rows(i).Item("fileName"))
_context.Response.Write("<div class='matchView'>")
While (rdr.Read)
matchID = rdr.Item("Current_Match_Index")
If venueLocation <> "" Then
venueLocation = ""
Else
venueLocation = br.getVenueLocation(matchID)
_context.Response.Write("<div class='matchTitle'>" + venueLocation + "</div>")
End If
set1 = IIf(IsDBNull(rdr.Item("SET_1")), " ", rdr.Item("SET_1"))
set2 = IIf(IsDBNull(rdr.Item("SET_2")), " ", rdr.Item("SET_2"))
set3 = IIf(IsDBNull(rdr.Item("SET_3")), " ", rdr.Item("SET_3"))
_context.Response.Write("<div class='" & teamClass & "'>")
If teamClass <> "TeamB" Then
teamClass = "TeamB"
Else
teamClass = "TeamA"
End If
serveIndicator = IIf(IsDBNull(rdr.Item("Service_Indicator")), "", rdr.Item("Service_Indicator"))
If serveIndicator = "" Then
serveImage = "<img src='images/css/serveIndicatorNone.png' alt='#' width='14' height='14' />"
Else
serveImage = "<img src='images/css/serveIndicator.png' alt='#' width='14' height='14' />"
End If
serveSpeed = IIf(IsDBNull(rdr.Item("Serve_Speed")), " ", "Serve: " & rdr.Item("Serve_Speed") & " km/h")
_context.Response.Write("<div class='flag'><img src='images/flags/" & rdr.Item("NOC") & ".jpg' alt='" & rdr.Item("NOC") & "' width='22' height='14' /></div><div class='NOC'>" & rdr.Item("NOC") & "</div><div class='serveIndicator'>" & serveImage & "</div><div class='teamName'>" & rdr.Item("Short_Team_Name") & "</div><div class='set1'>" & set1 & "</div><div class='set2'>" & set2 & "</div><div class='set3'>" & set3 & "</div><div class='serveSpeed'>" & serveSpeed & "</div>")
_context.Response.Write("</div>")
End While
_context.Response.Write("</div>")
rdr.Close()
Next
fsw.Dispose()
dsFiles.Dispose()
_context.Response.End()
_completed = True
_callback(Me)
End Sub
Private Sub OnChanged(ByVal sender As Object, ByVal e As FileSystemEventArgs)
mre.Set()
End Sub
Private Sub OnTimerChanged(ByVal sender As Object, ByVal e As ElapsedEventArgs)
mre.Set()
End Sub
End Class
Изменить №2: код для Broker.brCSV.readCSV (имя_файла)
Public Function readCSV(ByVal fileName As String) As OleDbDataReader
Dim rdr As OleDbDataReader = Nothing
Dim folderName = ("FolderName")
Dim cnString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & folderName & ";Extended Properties='text;HDR=Yes;FMT=Delimited';Mode=3"
Dim cn As New OleDb.OleDbConnection(cnString)
Dim cm As New OleDb.OleDbCommand("Select * from " & fileName, cn)
cm.Connection.Open()
rdr = cm.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
Return rdr
End Function
Обратите внимание на окончание строки подключения, особенно на параметр Mode
. В msdn указано, что именно так вы указываете права доступа к файлам, но могло случиться так, что я неправильно интерпретировал инструкции ... А именно, mode=3
должен указывать доступ к файлу как чтение / запись, но я не уверен, что это работает.
ИЗМЕНИТЬ № 3: новый Broker.brCSV.readCSV () выдает InvalidOperationException
В соответствии с предложениями доброго помощника Smudge202 я изменил код метода Broker.brCSV.readCSV следующим образом:
Public Function readCSV(ByVal fileName As String) As OleDbDataReader
Dim folderName = ("Folder Name")
Dim cnString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & folderName & ";Extended Properties='text;HDR=Yes;FMT=Delimited';Mode=3"
Using cn As New OleDb.OleDbConnection(cnString)
Using cm As New OleDb.OleDbCommand("Select * from " & fileName, cn)
cm.Connection.Open()
Dim rdr As OleDbDataReader = cm.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
Return rdr
End Using
End Using
End Function
Однако при тестировании этот код вызвал следующие ошибки:
Тип события: ошибка Источник события: ASP.NET 4.0.30319.0 Категория события: нет Идентификатор события: 1325 Дата: 22.04.2011 Время: 08:46:33 Пользователь: н / д Компьютер: EUW0002184 Описание: возникло необработанное исключение и процесс был прекращен.
Идентификатор приложения: / LM / W3SVC / 1 / ROOT
ID процесса: 6408
Исключение: System.InvalidOperationException
Сообщение: недопустимая попытка вызвать Read, когда считыватель закрыт.
StackTrace: в System.Data.OleDb.OleDbDataReader.Read () в SwatchTiming.AsynchOperation.StartAsyncTask (объект workItemState) в System.Threading.QueueUserWorkItemCallback.WaitCutionCollback_Context (состояние объекта) в System.Threading.Context (состояние объекта) в System.Threading.text (состояние объекта) в System.Threadation. , , Состояние объекта, логическое значение ignoreSyncCtx) в System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () в System.Threading.ThreadPoolWorkQueue.Dispatch () в System.Threading.WorkQueue.Dispatch () в System.Threadool.WorkQueue.
а также:
Тип события: ошибка Источник события: среда выполнения .NET Категория события: нет КОД события: 1026 Дата: 22.04.2011 Время: 08:47:53 Пользователь: нет Компьютер: EUW0002184 Описание: Приложение: w3wp.exe Версия платформы: v4.0.30319 Описание: Процесс был прерван из-за необработанного исключения. Информация об исключении: System.InvalidOperationException Стек: в System.Data.OleDb.OleDbDataReader.Read () в SwatchTiming.AsynchOperation.StartAsyncTask (System.Object) в System.Threading.QueueUserWorkItemCallback.WaitCallback_Contexting .runTryCode (System.Object) в System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup (TryCode, CleanupCode, System.Object) в System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext. ) в System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) в System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.Threading. .Dispatch () в System.Threading._ThreadPoolWaitCallback.PerformWaitCallback ()
Итак, когда обработчик пытается использовать новый метод readCSV, я получаю эти ошибки ... Какие-нибудь дальнейшие предложения? :) Спасибо Smudge, и спасибо всем остальным!