我开发了一个基于长轮询方法的实时评分应用程序,或者他们也称之为 Comet。我使用了在 IIS 6 上运行的 ASP.NET 4.0(Windows 2003 - 只有两个 CPU,这对池中线程的可用性没有多大帮助)。
数据以.csv
粘贴到 Web 服务器上的源文件夹的文件形式出现,然后我使用 Microsoft JET 4.0 OleDb Provider 将其导入,并根据应用程序的部分使用不同的方法显示。
长轮询部分的引擎依赖于,IHttpAsyncHandler.
因为它是一个实时评分应用程序,所以用户访问网站,获得带有当前数据的定期响应,并且在正文加载时通过 jquery ajax 向异步 http 处理程序发送新请求。
然后,该处理程序将请求存储在队列中,并(通常)将线程返回到线程池。一旦发生这种情况,我将创建一个手动重置事件并保持操作,同时创建并发送一个文件系统观察程序对象以查找 csv 数据源文件夹中的更改。
一旦它触发了一个onChange
事件,我就设置了手动重置事件,并且允许异步操作恢复并获取新的、刷新的 csv 文件并用新数据响应客户端。
如果我没有一直出错,这一切都会很好。一般来说,非常非常一般的方式,应用程序正在运行,但我有一个我不能完全指出的问题。
也就是说,我不确定问题是否与访问 csv 文件有关,因为它们可能被将它们带入服务器的过程锁定(从体育场馆进行 ftp 传输)。或者可能是我(ab)使用IHttpAsyncHandler
了知道小时数)。
具有两个 CPU 的 IIS 6 windows 2003 是否可能无法支持此类应用程序?
这是我不断收到的错误:
事件类型:错误事件源:ASP.NET 4.0.30319.0 事件类别:无事件 ID:1325 日期:2011 年 4 月 20 日时间:15:33:14 用户:N/A 计算机:xxx 描述:发生未处理的异常并且该过程已终止。
应用程序 ID:/LM/W3SVC/1/ROOT 进程 ID:5264 异常:System.Data.OleDb.OleDbException 消息:未指定的错误
StackTrace:在 System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString 常量,OleDbConnection 连接)
在 System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions 选项,对象 poolGroupProviderInfo,DbConnectionPool 池,DbConnection owningObject) 在 System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection,DbConnectionPoolGroup poolGroup) 在 System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection owningConnection) 在 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) 在 System.Data.OleDb.OleDbConnection.Open() 在 Broker.brCSV.readCSV(String fileName) 在 SwatchTiming.AsynchOperation.StartAsyncTask( System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) 处的对象 workItemState) System.Threading。System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 处 System.Threading 处的 ExecutionContext.runTryCode(Object userData)。 ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback ()CleanupCode backoutCode, Object userData) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading。 QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()CleanupCode backoutCode, Object userData) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading。 QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()Boolean ignoreSyncCtx) 在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()Boolean ignoreSyncCtx) 在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue.Dispatch() 在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
并且:
事件类型:错误事件源:.NET 运行时 4.0 错误报告事件类别:无事件 ID:5000 日期:20/04/2011 时间:15:33:14 用户:N/A计算机: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 3。 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.ea3.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 0 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 40 0 4e 0.0 0.0.0 0d 00 0a 00 IL....
和...
事件类型:错误事件源:.NET 运行时事件类别:无事件 ID:1026 日期:2011 年 4 月 20 日时间: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.Object) 在 System.Runtime.CompilerServices.RuntimeHelpers。 ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object) 在 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, 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(fileName) 的代码
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 事件类别:无事件 ID:1325 日期:22/04/2011 时间:08:46:33 用户:N/A 计算机:EUW0002184 描述:发生未处理的异常并且该过程已终止。
应用程序 ID:/LM/W3SVC/1/ROOT
进程 ID:6408
异常:System.InvalidOperationException
消息:阅读器关闭时调用 Read 的尝试无效。
StackTrace:在 System.Data.OleDb.OleDbDataReader.Read() 在 SwatchTiming.AsynchOperation.StartAsyncTask(Object workItemState) 在 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) 在 System.Threading.ExecutionContext.runTryCode(Object userData) 在 System .Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback , 对象状态, Boolean ignoreSyncCtx) 在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 在 System.Threading.ThreadPoolWorkQueue。System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() 处的 Dispatch()
也:
事件类型:错误事件源:.NET 运行时事件类别:无事件 ID:1026 日期:22/04/2011 时间:08:47:53 用户:N/A 计算机:EUW0002184 描述:应用程序:w3wp.exe 框架版本: v4.0.30319 描述:进程因未处理的异常而终止。异常信息:System.InvalidOperationException 堆栈:在 System.Data.OleDb.OleDbDataReader.Read() 在 SwatchTiming.AsynchOperation.StartAsyncTask(System.Object) 在 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object) 在 System.Threading.ExecutionContext .runTryCode(System.Object) 在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object) 在 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading。
因此,当处理程序尝试使用新的 readCSV 方法时,我会收到这些错误...还有什么建议吗?:) 谢谢涂抹,也谢谢其他人!