速度数据处理:带事件的ThreadPool或Thread循环?

时间:2014-06-11 06:44:24

标签: c# multithreading threadpool

我需要在另一个线程中处理数据。它可以通过两种方式完成:

  1. 使用等待事件的线程循环:

    AutoResetEvent e = new AutoResetEvent(false)
    Thread t = new Thread(delegate
    {
      while(true)
      {
        e.WaitOne();
        // process data
      }
    };)
    
    void OnProgramStarted() // one time
    {
      t.Start();
    }
    
    void OnDataReceived()
    {
      // put data to queue
      e.Set();
    }
    
  2. 使用线程池:

    void ProcessData(object state)
    {
      // process data
    }
    
    void OnDataReceived()
    {
      // put data to queue
      ThreadPool.QueueUserWorkItem(ProcessData);
    }
    
  3. 哪种方式会更快?
    真实的测试结果不明确。

    我的基准代码:

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace t_event_tpool
    {
      class Program
      {
        const int t = 1000000;
    
        static Stopwatch sw = new Stopwatch();
        static int q1, q2;
    
    
        static AutoResetEvent e1 = new AutoResetEvent(false);
        static AutoResetEvent done1 = new AutoResetEvent(false);
    
        static Thread thread = new Thread(ThreadProc);
        static void ThreadProc(object state)
        {
          while(true)
          {
            e1.WaitOne();
            q1++;
            done1.Set();
          }
        }
    
    
        static AutoResetEvent done2 = new AutoResetEvent(false);
    
        static void PoolProc(object state)
        {
          q2++;
          done2.Set();
        }
    
    
        static void TestA()
        {
          sw.Restart();
          for(int i = 0; i < t; i++)
          {
            e1.Set();
            done1.WaitOne();
          }
          sw.Stop();
          Console.WriteLine("a " + sw.ElapsedMilliseconds + "\t" + q1);
        }
    
        static void TestB()
        {
          sw.Restart();
          for(int i = 0; i < t; i++)
          {
            ThreadPool.QueueUserWorkItem(PoolProc, i);
            done2.WaitOne();
          }
          sw.Stop();
          Console.WriteLine("b " + sw.ElapsedMilliseconds + "\t" + q2);
        }
    
    
    
        static void Main(string[] args)
        {
          thread.IsBackground = true;
          thread.Start();
    
          TestA();
          TestB();
    
          TestA();
          TestB();
    
          TestA();
          TestB();
        }
      }
    }
    

    低CPU负载(没有其他应用程序)TestB比TestA快2倍。其他进程TestA的高CPU负载比TestB更快。

1 个答案:

答案 0 :(得分:1)

您正在测试开始工作的开销。这对于实际工作的速度毫无意义。而不是优化开销,使您的工作项更精细,以便开销无关紧要。如果你的工作项目运行速度超过0.1毫秒,我会认真考虑让它们更大。在您的测试中,您的工作项只需要一些说明。

回答这个问题:准备好在事件信号下运行的自定义线程比将工作项发布到线程池的开销要小。你什么也没做。难以改善。您需要使用像Disruptor模式这样的高速排队模式。