什么更好的做我们必须异步执行方法比BlockingCollect

什么更好的做我们必须异步执行方法比BlockingCollect

本文介绍了有什么更好的做我们必须异步执行方法比BlockingCollection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了这样的例子来衡量如何快速BlockingCollection对于异步执行

 使用系统;
使用System.Collections.Concurrent;
使用System.Diagnostics程序;
使用的System.Threading;
使用System.Threading.Tasks;命名空间TestBlockingCollection
{
    类节目
    {
        静态无效的主要(字串[] args)
        {
            BlockingCollection< INT> blockingCollection =新BlockingCollection<&诠释GT;();
            秒表SW = Stopwatch.StartNew();            Task.Factory.StartNew(()=>
            {
                INT I = 0;
                而(真)
                {
                    Console.WriteLine(添加+ I);
                    SW = Stopwatch.StartNew();
                    blockingCollection.Add(我++);
                    Thread.sleep代码(1000);
                }
            });            Task.Factory.StartNew(()=>
            {
                而(真)
                {
                    INT I = blockingCollection.Take();
                    sw.Stop();
                    长微秒= sw.ElapsedTicks /(Stopwatch.Frequency /(1000L * 1000L));
                    Console.WriteLine(收到+ I + + +微秒微秒。花);
                }
            });            而(真)
            {
                Thread.sleep代码(1000);
            }
        }
    }
}

结果很失望:

 添加0
为0分花19593微秒。
加入1
1.收到花220微秒。
添加2
2.收到的花38微秒。
添加3
3.收到花104微秒。
添加4
4.收到了46微秒。
加入5
5.收到了37微秒。
加入6
6,收到的废112微秒。
添加7
7.收到的花103微秒。
添加8
8.收到的花104微秒。
添加9
9.收到的花384微秒。
加入10
10.收到的102花微秒。
添加11
11.收到了39微秒。
添加12
12.收到的花51微秒。
添加13
13.收到的花42微秒。
添加14
14.收到的花了40微秒。
加入15
15.收到的花了40微秒。
添加16
16.收到的花42微秒。
添加17
17.收到的花了40微秒。
加入18
18.收到的花41微秒。
添加19
19.收到的花42微秒。
加入20
20.收到的花62微秒。
添加21
21.收到了36微秒。
添加22
22.收到了39微秒。
添加23
23.收到了35微秒。
添加24
24.收到的花了40微秒。
加入25
25.收到的花63微秒。
添加26
26.收到的花56微秒。
添加27
27.收到的花42微秒。
添加28
28.收到的花41微秒。
添加29
29.收到的花42微秒。
加入30
30.收到的花41微秒。
添加31
31.收到的651花微秒。
添加32
32.收到了43微秒。
添加33
33.收到的花58微秒。
添加34
34.收到了43微秒。
添加35
35.收到的花41微秒。
添加36
36.收到的花59微秒。
添加37
37.收到的花38微秒。
添加38
38.收到的花38微秒。
添加39
39.收到的花38微秒。
加入40
40.收到的花42微秒。
添加41
41.收到的花59微秒。
添加42
42.收到的花了40微秒。
添加43
43.收到的花42微秒。
添加44
44.收到的花41微秒。
添加45
45.收到了39微秒。
添加46
46.​​收到的花42微秒。
添加47
47.收到的花41微秒。
添加48
48.收到的花41微秒。
添加49
49.收到的花42微秒。
加入50
50.收到了35微秒。
添加51
51.收到的花42微秒。
添加52
52.收到了39微秒。
添加53
53.收到了43微秒。
添加54
54.收到了35微秒。
添加55
55.收到的花60微秒。
添加56
56.收到的花59微秒。
添加57
57.收到的花55微秒。
添加58
58.收到的花74微秒。
添加59
59.收到的花56微秒。
添加60
60.收到的花42微秒。

在平均花了我50微秒左右,但有时我花了高达600微秒!

即使使用我慢的Pentium U5400我预计应该是恒定的几个,不超过10个,且绝不超过10微秒。

什么更快的方法.NET具有异步EXEC?异步EXEC计划后,我需要尽快开始。这是financical时间敏感的计算。

禁止收集garantees顺序和项目将被处理逐一garantees,所以这个问题实际上包含了两个问题


  1. 我们有更快的东西,如果我需要秩序,我需要的顺序来处理的项目又相继出现?即我需要FIFO查询。

  2. 请我们的东西,如果我不在乎为了更快,我不在乎,如果项目由一个或平行?
  3. 逐个处理

我猜的答案是:


  1. 没有。我必须使用BlockingCollection为引用is它很好用BlockingCollection< T>单生产者,单消费者FIFO查询?


  2. 我可能会尝试委托?



解决方案

实验了好几个小时,我认为这是公司获得的方式测量后;我改成了10000运行,结果是:

The code is pretty much as yours (it's below for reference); I did do a release build

I experimented with using a Barrier but it was slower. I also tried to do it using just locks but failed to get that working.

   static void Main(string[] args)
    {
        var barrier = new Barrier(2);
        var collection = new List<int>();
        var num_iterations = 100000;
        var iterations = num_iterations;
        var total_time_ms = 0.0M;

        Stopwatch sw = new Stopwatch();


        total_time_ms = 0.0M;
        iterations = num_iterations;

        var blockingCollection = new BlockingCollection<int>();

        Task.Factory.StartNew(() =>
        {
            int i = 0;

            while (iterations-- > 0)
            {
                sw.Restart();
                blockingCollection.Add(i++);
            }
        });


        Task.Factory.StartNew(() =>
        {
            var expected_value = 0;

            while (iterations > 0) // stop when performed certain number
            {
                int i = blockingCollection.Take();
                sw.Stop();
                long microseconds = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
                total_time_ms += microseconds;
                if (i != expected_value)
                    Console.WriteLine(String.Format("** expected {0} got {1}", i, expected_value));
                expected_value++;
            }
        });
        while (iterations > 0)
        {
            Thread.Sleep(1000);
        }
        Console.WriteLine(String.Format("Total {0} for {1} iterations, average {2}", total_time_ms, num_iterations, total_time_ms / num_iterations));

I believe that BlockingCollection is a good collection to use for this. There are other ways of doing it but this is a complicated area and the chances of getting something faster than this are unlikely.

这篇关于有什么更好的做我们必须异步执行方法比BlockingCollection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 05:37