1

私は、ロング ポーリング アプローチに基づくライブ スコアリング アプリケーションを開発しました。これは、コメットとも呼ばれます。IIS 6 で動作する ASP.NET 4.0 を使用しました (windows 2003 - CPU が 2 つしかないため、プール内のスレッドの可用性についてはあまり役に立ちません)。

データは.csv、Web サーバーのソース フォルダーに貼り付けられたファイルの形式で入ってきます。これを Microsoft JET 4.0 OleDb プロバイダーを使用してインポートし、アプリケーションの部分に応じてさまざまな方法を使用して表示します。

ロング ポーリング部分のエンジンIHttpAsyncHandler.は、ライブ スコアリング アプリケーションであるため、ユーザーは Web サイトにアクセスし、現在のデータを含む通常の応答を取得し、ボディ ロードで jquery ajax を介して非同期 http ハンドラーに新しい要求を送信します。

次に、このハンドラーは要求をキューに格納し、(通常は) スレッドをスレッド プールに戻します。これが発生したら、手動リセット イベントを作成して操作を保留します。その間、ファイル システム ウォッチャー オブジェクトが作成されて送信され、csv データ ソース フォルダー内の変更が検出されます。

イベントが発生したらonChange、手動リセット イベントを設定します。非同期操作は、新しく更新された csv ファイルを取得して再開し、クライアントに新しいデータで応答することが許可されます。

常にエラーが発生していない場合、これはすべて素晴らしいことです。一般的に、非常に一般的な方法で、アプリケーションは機能していますが、特定できない問題があります。

つまり、csv ファイルをサーバーに取り込むプロセス (スポーツ会場からの ftp 転送) によって csv ファイルがロックされている可能性があるため、csv ファイルへのアクセスに問題があるかどうかはわかりません。それとも、私の (乱用) の使用なのIHttpAsyncHandlerか、それとも CPU とスレッドが不足しているだけなのか (毎日約 3000 のユニークな訪問者しかいないため、信じがたいと思います。私はそうではありません)時間ごとの数字を知っている)。

2 つの CPU を搭載した IIS 6 Windows 2003 がこの種のアプリケーションをサポートできない可能性はありますか?

ここに私が得続けるエラーがあります:

イベントの種類: エラー イベント ソース: ASP.NET 4.0.30319.0 イベント カテゴリ: なし イベント ID: 1325 日付: 20/04/2011 時刻: 15:33:14 ユーザー: N/A コンピューター: xxx 説明: 未処理の例外が発生し、プロセスは終了しました。

アプリケーション ID: /LM/W3SVC/1/ROOT プロセス ID: 5264 例外: System.Data.OleDb.OleDbException メッセージ: 不明なエラー

スタック トレース: 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 プール グループ) で 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(オブジェクト workItemState) System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(オブジェクト状態) で System.Threading.System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode コード、CleanupCode backoutCode、オブジェクト userData) での ExecutionContext.runTryCode (オブジェクト userData) System.Threading.ExecutionContext.RunInternal (ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態) で System.Threading。 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() での ExecutionContext.Run (ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態、ブール値の ignoreSyncCtx) System.Threading.ThreadPoolWorkQueue.Dispatch() で System.Threading._ThreadPoolWaitCallback.PerformWaitCallback ()System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態) で System.Threading.ExecutionContext.Run(ExecutionContext 実行コンテキスト、ContextCallback コールバック、オブジェクト状態、ブール値の ignoreSyncCtx) で System.Threading.Threading で。 QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() System.Threading.ThreadPoolWorkQueue.Dispatch() で System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態) で System.Threading.ExecutionContext.Run(ExecutionContext 実行コンテキスト、ContextCallback コールバック、オブジェクト状態、ブール値の ignoreSyncCtx) で System.Threading.Threading で。 QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() System.Threading.ThreadPoolWorkQueue.Dispatch() で System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() のブール値 ignoreSyncCtx) System.Threading.ThreadPoolWorkQueue.Dispatch() の System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() のブール値 ignoreSyncCtx) 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
のヘルプとサポート センターを参照してください 。 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 ed b. 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 000 20 00 4e 00: N 0.4e 00 0d 00 0a 00 イル....

と...

イベントの種類: エラー イベント ソース: .NET ランタイム イベント カテゴリ: なし イベント ID: 1026 日付: 2011/04/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.文字列) で [ProjectNamespace].AsynchOperation.StartAsyncTask(System.Object) で System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object) で System.Threading.ExecutionContext.runTryCode(System.Object) で System.Runtime.CompilerServices.RuntimeHelpers. System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) での ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, 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 を微調整しようとしましたが、あまり役に立たないようです。

では一体何が起こっているのか、なぜ私のサイトが 5 分ごとにクラッシュするのか、わかる人はいますか?

編集:これがハンドラーの私のコードです。これが役立つことを願っています

BeginProcessRequest次のとおりです(それ以外は、IsReusablefalse に設定しているだけです):

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")), "&nbsp;", rdr.Item("SET_1"))
            set2 = IIf(IsDBNull(rdr.Item("SET_2")), "&nbsp;", rdr.Item("SET_2"))
            set3 = IIf(IsDBNull(rdr.Item("SET_3")), "&nbsp;", 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")), "&nbsp;", "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(オブジェクト workItemState) で System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(オブジェクト状態) で System.Threading.ExecutionContext.runTryCode(オブジェクト userData) で System. .Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode コード、CleanupCode backoutCode、オブジェクト userData) System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback コールバック) 、オブジェクトの状態、ブール値の ignoreSyncCtx) (System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() で System.Threading.ThreadPoolWorkQueue で)。System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() で Dispatch()

としても:

イベントの種類: エラー イベント ソース: .NET ランタイム イベント カテゴリ: なし イベント ID: 1026 日付: 2011/04/22 時刻: 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_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 メソッドを使用しようとすると、これらのエラーが発生します...さらに提案はありますか? :) Smudge さん、ありがとうございました。

4

1 に答える 1