2011-06-19 19 views
4

私はdbに挿入する必要がある膨大な統計データを受け取ります。 すべてのデータを保持する何らかの種類のキューまたはFIFOクラスを実装したいと思います。 特定のカウント(バッファ)に達すると、バルク挿入を介してそのデータをSQLに送信します。これはスレッドセーフである必要があります。バッファとスレッドセーフのFIFO/QUEUE

バルクインサートの作成方法はわかっています。 どのようにキュー/リストを作成するアドバイスですか?

おかげ

+0

なぜFIFOである必要がありますか? – adrianm

+0

あなたは.Net 4で動作していますか? – svick

答えて

1

.NETベースクラスライブラリはConcurrentQueue(Of T)ています。ちょうどをインポートしてください。

:キューを使用する必要がある場合は、カウンタ(バッファ)が一定量に達したときにイベントを発生させるラッパークラス/モジュールを作成できます。

+0

スレッドセーフ... –

+0

バッファ制限に達してスレッドセーフである場合のコールバック機能はどうですか? – Shay

+0

@Henk - Ahhh。それは単純すぎると思った... – aligray

0

厳密なFIFOが必要ない場合は、BlockingCollectionを使用する必要があります。

これは、スレッドセーフであると実装は次のように気にいらになります:

var collection = new BlockingCollection<Data>(); 

var sqlinserter = Task.Factory.StartNew(UpdateSql()); 

while (true) { 
    Data statistics = FetchStatistics(); 
    if (statistics == null) 
     break; 
    collection.Add(statistics); 
} 
collection.CompleteAdding(); 
sqlinserter.Wait(); 

を編集します各バッチ内の項目の具体的な数を挿入したい ソウは

void UpdateSql() { 
    var batch = new List<Data>(); 
    foreach (var item in collection.GetConsumingEnumerable()) { 
     batch.Add(item); 
     if (batch.Count > SomeBatchSize) { 
      InsertIntoSql(batch); 
      batch.Clear(); 
     } 
    } 
    if (batch.Count > 0) 
     InsertIntoSql(batch); // insert remaining items 
} 
-1

これは、それに対処する安全な方法です。 主に、あなたがsynclockの中で「スタック」することができる状況を避けたいとします。

Public Class TSQueue(Of T) 

    Private q As New Queue(Of T) 
    Public Property threshold As Integer = 100 
    Public Event ThresholdHit As EventHandler(Of EventArgs) 

    Public Sub EnqueueSafe(value As T) 
     Dim notify As Boolean = False 
     SyncLock q 
      q.Enqueue(value) 
      If q.Count >= threshold Then 
       notify = True 
      End If 
     End SyncLock 
     If notify Then 
      RaiseEvent ThresholdHit(Me, EventArgs.Empty) 
     End If 
    End Sub 

    Public Function DequeueSafe() As T 
     SyncLock q 
      Return q.Dequeue() 
     End SyncLock 
    End Function 

    Public Function DequeueAllSafe() As T() 
     Dim out() As T 
     SyncLock q 
      out = q.ToArray() 
      q.Clear() 
     End SyncLock 
     Return out 
    End Function 

    Public Function CountSafe() As Integer 
     SyncLock q 
      Return q.Count 
     End SyncLock 
    End Function 

End Class 
+0

質問が効果的だったので、これは答えではない "と驚いている...すべてのデータを保持している特定の種類のキューまたはFIFOクラスを実装し、 )、それは一括挿入を介してSQLにそのデータを送信します。これはスレッドセーフでなければなりません。イベントThresholdHitはデータのダンプをトリガーし、バックグラウンドキューはsynclockステートメントを介してスレッドセーフです。 – DarrenMB

関連する問題