如何同时从BlockingCollection中获取项目?

时间:2017-03-27 20:41:26

标签: c# multithreading multitasking blockingcollection

我有SqlQuerySpec个整数。 以下是我正在尝试开发的代码,以便同时从var query = new SqlQuerySpec("SELECT * FROM Documents d WHERE IS_DEFINED(d.property)"); IDocumentQuery<TEntity> queryable = client.CreateDocumentQuery<TEntity>(documentCollectionUri, query) .Where(c=>c.Name!="raju") .AsDocumentQuery(); 中删除项目。

BlockingCollection

这是通过创建5个任务以更快的方式删除项目的正确方法吗?

1 个答案:

答案 0 :(得分:3)

秒表问题

您的测量结果错误,因为您使用

stopWatch.Elapsed.Seconds

而不是

stopWatch.ElapsedMilliseconds

您只显示秒数,但忽略分钟,小时等

并发问题

不,这不是从BlockingCollection中删除项目的正确方法。不起作用的陈述是

bc3.Count != 0

所有5个任务可以同时检查这个条件,发现剩下1个项目。他们都去了

bc3.Take();

一个任务可以删除该项目,其他4个任务正在等待。

解决此问题的一种方法是添加

bc3.CompleteAdding();
Produce()中的

垃圾收集问题

第一个任务完成后,Run()方法完成,方法中的所有任务都超出范围并被垃圾回收。这可能会让您只看到1条而不是5条完成消息。

要解决此问题,请使用

    static void Run()
    {
        var tasks = new List<Task>();
        for (int i = 0; i < 5; i++)
        {
            tasks.Add(Task.Factory.StartNew(Process, TaskCreationOptions.LongRunning));
        }
        try
        {
            Task.WaitAll(tasks.ToArray());
        }
        catch (AggregateException)
        { }        
    }

同步成本

这是我的一个输出,包含5个任务(和100000000个项目):

Thread 11
Thread 13
Thread 12
Thread 14
Thread 15
Elapsed Time 12878
Elapsed Time 13122
Elapsed Time 13128
Elapsed Time 13128
Elapsed Time 13128
Run: 13140

将此与单个任务进行比较:

Thread 12
Elapsed Time 10147
Run: 10149

这是因为只有一个Take()方法可以删除一个项目,并且需要额外的时间进行同步。