2017-11-06 18 views
1

イベントをキューに入れて並列に実行する必要があります。ThreadPoolがイベントを逃す

C#コードは、イベントをブロッキングコレクション内にキューイングし、ThreadPoolを使用してワーカースレッド上で各イベントを実行します。ただし、イベントが2000イベント/秒以上のレートでキューに入れられている場合は、一部のイベントが表示されません。 、さらに悪いことに

スレッドからスレッドに依存して着信要求:私はこの問題のために検索すると、私はThreadPoolのは、いくつかの要求を拒否またはどのスレッドが利用できない場合this linkから、それらを保持できることが判明しましたプールは保留状態にあってもよいし、スレッドプールは、着信要求

注処理するためにそれで使用可能なスレッドを持っていない可能性があるためも、主にを拒否される可能性があります。この問題は、コアi5でノートパソコンを使用している場合にのみ表示されますが、 Core i7で試したところ、正しく動作しました。

は、ここでのコードの抜粋です:

public static void ExecuteEvents() 
{ 
    foreach (EventData data in blockingCollection.GetConsumingEnumerable()) 
    { 
     switch (data.EventType) 
     { 
      case EventType1: 
       ThreadPool.QueueUserWorkItem(o => 
       { 
        Function1(data); 
       }); 
       break; 
      case EventType2: 
       ThreadPool.QueueUserWorkItem(o => 
       { 
        Function2(data); 
       }); 
      default: 
       break; 
     } 
    } 
} 
+3

「ThreadPool」によって拒否された作業項目について聞いたことがありません。それは別のものだと思う。 –

+0

他の原因についてどう思いますか? @ JeroenvanLangen –

+0

あなたの神秘的な消滅するものがeventtyp1または2ではないと判断した場合、いくつかのログを追加しようとしましたか? – BugFinder

答えて

3

あなたはスレッドプールに問題を抱えているようですが見えません。閉鎖に問題があるようです。

ループ内でローカル変数を最初に作成する必要があります。問題は、スレッドプールがアクションを実行するときに、常に変更される変数EventData dataを参照していることです。したがって、あなたは最初にローカル変数を作成する必要があります。(ローカル変数がスコープ外のリストに入れているメソッドから参照されているため、displayclassにパックされる。)

public static void ExecuteEvents() 
{ 
    foreach (EventData data in blockingCollection.GetConsumingEnumerable()) 
    { 
     var local = data; 
     switch (local.EventType) 
     { 
      case EventType1: 
       ThreadPool.QueueUserWorkItem(o => 
       { 
        Function1(local); 
       }); 
       break; 
      case EventType2: 
       ThreadPool.QueueUserWorkItem(o => 
       { 
        Function2(local); 
       }); 
      default: 
       break; 
     } 
    } 
} 

を閉鎖に関する詳しい情報についてlook here

+0

私はそれを試みましたが、まだ動作していません。 –

+1

OPがC#3.0以前であった場合、これは当てはまります。これは、C#4.0 +を使用している場合は変更されません。そのコメントに基づいて、そのように見えます。 – Servy

関連する問題