微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

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();
}

>使用线程池:

void ProcessData(object state)
{
  // process data
}

void OnDataReceived()
{
  // put data to queue
  ThreadPool.QueueUserWorkItem(ProcessData);
}

什么方式会更快?
真实的测试给出了模棱两可的结果.

我的基准代码

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倍.其他进程的高cpu负载TestA比TestB更快.

解决方法

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐