我正在接收大量需要插入到数据库中的统计数据。 我想实现某种类型的队列或FIFO类,它保留所有数据 ,并且当它到达特定计数(缓冲区)时,它将通过批量插入将该数据发送到SQL。这应该是线程安全的。带缓冲区和线程安全的FIFO/QUEUE
我知道如何制作批量插入。 任何建议如何使队列/列表?
感谢
我正在接收大量需要插入到数据库中的统计数据。 我想实现某种类型的队列或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
为什么它需要先进先出? – adrianm
你在.Net 4下运行吗? – svick