私はdbに挿入する必要がある膨大な統計データを受け取ります。 すべてのデータを保持する何らかの種類のキューまたはFIFOクラスを実装したいと思います。 特定のカウント(バッファ)に達すると、バルク挿入を介してそのデータをSQLに送信します。これはスレッドセーフである必要があります。バッファとスレッドセーフのFIFO/QUEUE
バルクインサートの作成方法はわかっています。 どのようにキュー/リストを作成するアドバイスですか?
おかげ
私はdbに挿入する必要がある膨大な統計データを受け取ります。 すべてのデータを保持する何らかの種類のキューまたはFIFOクラスを実装したいと思います。 特定のカウント(バッファ)に達すると、バルク挿入を介してそのデータをSQLに送信します。これはスレッドセーフである必要があります。バッファとスレッドセーフのFIFO/QUEUE
バルクインサートの作成方法はわかっています。 どのようにキュー/リストを作成するアドバイスですか?
おかげ
厳密な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
}
これは、それに対処する安全な方法です。 主に、あなたが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
質問が効果的だったので、これは答えではない "と驚いている...すべてのデータを保持している特定の種類のキューまたはFIFOクラスを実装し、 )、それは一括挿入を介してSQLにそのデータを送信します。これはスレッドセーフでなければなりません。イベントThresholdHitはデータのダンプをトリガーし、バックグラウンドキューはsynclockステートメントを介してスレッドセーフです。 – DarrenMB
なぜFIFOである必要がありますか? – adrianm
あなたは.Net 4で動作していますか? – svick