具有缓冲区和线程安全的FIFO/QUEE

本文关键字:FIFO QUEE 安全 线程 缓冲区 | 更新日期: 2023-09-27 17:59:39

我收到了大量需要插入数据库的统计数据。我想实现某种保存所有数据的队列或FIFO类当它达到特定计数(缓冲区)时,它将通过大容量插入将该数据发送到SQL。这应该是线程安全的。

我知道如何制作大块插件。有什么建议吗?

感谢

具有缓冲区和线程安全的FIFO/QUEE

.net基类库具有ConcurrentQueue(Of T)。只需导入System.Collections.Concurrent

编辑:如果必须使用队列,可以创建一个包装类/模块,当计数器(缓冲区)达到一定数量时,该类/模块会触发事件。

如果您不需要严格的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
}

这是一种安全的处理方法。首先,您希望避免出现任何可能被"卡"在同步锁中的情况。

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