2011-06-19 90 views
4

我正在接收大量需要插入到数据库中的统计数据。 我想实现某种类型的队列或FIFO类,它保留所有数据 ,并且当它到达特定计数(缓冲区)时,它将通过批量插入将该数据发送到SQL。这应该是线程安全的。带缓冲区和线程安全的FIFO/QUEUE

我知道如何制作批量插入。 任何建议如何使队列/列表?

感谢

+0

为什么它需要先进先出? – adrianm

+0

你在.Net 4下运行吗? – svick

回答

1

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

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

+0

然后线程安全.... –

+0

当达到缓冲区限制并将其作为线程安全时,回调函数如何? – Shay

+0

@亨克 - 啊。认为它太简单了...... – 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