簡體   English   中英

線程安全緩沖區

[英]Thread-safe buffer

我正在實現某種緩沖機制:

private static readonly ConcurrentQueue<ProductDto> ProductBuffer = new ConcurrentQueue<ProductDto>();

private async void On_ProductReceived(object sender, ProductReceivedArgs e)
{
    ProductBuffer.Enqueue(e.Product);

    if (ProductBuffer.Count >= handlerConfig.ProductBufferSize)
    {
        var products = ProductBuffer.ToList();
        ProductBuffer.Clear();

        await SaveProducts(products);
    }
}

問題是-我是否應該麻煩地添加某種鎖,以確保沒有數據丟失(假設某些其他線程會在buffer.ToList()之后和buffer.Clear()之前添加乘積,假設是:),或ConcurrentQueue將為我處理所有骯臟的工作?

您可以這樣做:

if (ProductBuffer.Count < handlerConfig.ProductBufferSize)
    return;

var productsToSave = new List<Product>();
Product dequeued = null;
while(ProductBuffer.TryDequeue(out dequeued))
{
    productsToSave.Add(dequeued);
}
SaveProducts(products);

您永遠不會Clear隊列。 您只要不斷取出東西,直到它變空為止。 如果您不想一次保存太多產品,或者當productsToSave達到一定大小時可以停止處理,處理該列表,然后開始新的列表。

這樣,是否將新項目添加到隊列都沒有關系。 如果在您從隊列中讀取時添加了它們,它們也會被讀取。 如果是在您停止從隊列中讀取后才添加的,則它們將在那里並在隊列下一次充滿並處理時讀取。

ConcurrentQueue的要點是,您可以添加到其中並從多個線程中讀取它,而無需lock


如果要這樣做:

    productsToSave = ProductBuffer.ToList();

    ProductBuffer.Clear();

那么您將需要該lock (這將無法達到目的。)大概您正在使用ConcurrentQueue因為可能有多個線程將項目添加到隊列中。 如果真是這樣,那么在這兩個語句的執行之間完全有可能進入隊列。 它不會添加到列表中,但會被Clear刪除。 該項目將丟失。

這是我要實現的方式,我假設不需要在保存完成時通知您?

private void On_ProductReceived(object sender, ProductReceivedArgs e)
{
    // Variable to hold potential list of products to save
    List<Products> productsToSave;

    // Lock buffer
    lock(ProductBuffer)
    {
        ProductBuffer.Enqueue(e.Product);

        // If it is under size, return immediately
        if (ProductBuffer.Count < handlerConfig.ProductBufferSize)
            return;

        // Otherwise save products, clear buffer, release lock.
        productsToSave = ProductBuffer.ToList();

        ProductBuffer.Clear();
    }

    // Save Produts, 

    SaveProducts(products);
}

如果您只獲得1種產品,而又什么也沒有得到,怎么辦?您是否不想在超時后保存該產品?

我會在您的用例中使用Rx東西,尤其是IObservable<T>.Buffer(count)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM