C#并行和任务太慢

C#并行和任务太慢,c#,parallel-processing,C#,Parallel Processing,我有一个问题,试图在4秒内完成工作,无论是使用并行或任务时间表或任何东西。这个脚本很简单,它将尝试一次处理100次,然后等待结果。我的电脑是E5-2603 Xeon处理器(4核,4线程,1.80GHz),16GB,它花了很长时间才能处理100个任务 我可以做些什么来加快这个过程 测试脚本 static void Main(string[] args) { //Monitor performance Stopwatch totalTi

我有一个问题,试图在4秒内完成工作,无论是使用并行或任务时间表或任何东西。这个脚本很简单,它将尝试一次处理100次,然后等待结果。我的电脑是E5-2603 Xeon处理器(4核,4线程,1.80GHz),16GB,它花了很长时间才能处理100个任务

我可以做些什么来加快这个过程

测试脚本

static void Main(string[] args)
        {
            //Monitor performance
            Stopwatch totalTime = new Stopwatch();


            //Test case # 1
            totalTime.Start();
            TaskTechnique();
            totalTime.Stop();
            Console.WriteLine("TaskTechnique total time: " + totalTime.Elapsed.TotalSeconds);
            Console.WriteLine("--------------------------------------");

            //Test case #2
            totalTime.Reset();
            totalTime.Start();
            ParalelelTechnique();
            totalTime.Stop();
            Console.WriteLine("ParalelelTechnique total time: " + totalTime.Elapsed.TotalSeconds);
            Console.WriteLine("--------------------------------------");

        }

处理100个小任务需要21秒。代码如下

    /// <summary>
    /// Using task to process all tasks
    /// </summary>
    private static void TaskTechnique()
    {

        //Test case 1 process all 100 tasks at once
        List<Task<string>> tasks = new List<Task<string>>();
        for (int i = 0; i < 100; i++)
        {
            tasks.Add(
                    Task.Factory.StartNew
                    (
                            () =>
                            {
                                return MrDelay(i);
                            }
                    )
                );
        }

        Task.WaitAll(tasks.ToArray());//Wait until finished 
    }
//
///使用任务处理所有任务
/// 
私有静态void tasktechnology()
{
//测试用例1一次处理所有100个任务
列表任务=新列表();
对于(int i=0;i<100;i++)
{
任务。添加(
Task.Factory.StartNew
(
() =>
{
返回延迟(i);
}
)
);
}
Task.WaitAll(tasks.ToArray());//等待完成
}
,处理过程耗时33秒

  /// <summary>
        /// Using Paralelel to process 100 times
        /// </summary>
        private static void ParalelelTechnique()
        {
            //Monitor performance
            Stopwatch startTime = new Stopwatch();
            //Test case 2 using parallel
            startTime.Restart();
            int maxTask = 100;
            var result = Parallel.For
                (
                1, 101,
                new ParallelOptions { MaxDegreeOfParallelism = maxTask },
                (i, state) =>
                {
                    Console.WriteLine("Beginning iteration {0} at ", i, DateTime.Now.ToLocalTime());
                    string longTaskResult = MrDelay(i);
                    Console.WriteLine("Completed iteration {0} result at : {1}", i, longTaskResult);
                }
                );
            startTime.Stop();
            Console.WriteLine("test case 2: " + startTime.Elapsed.TotalSeconds);
        }
//
///采用并行处理100次
/// 
专用静态空隙并行技术()
{
//监控性能
秒表开始时间=新秒表();
//使用并行测试的测试用例2
startTime.Restart();
int-maxTask=100;
var result=Parallel.For
(
1, 101,
新的并行选项{MaxDegreeOfParallelism=maxTask},
(一、州)=>
{
WriteLine(“开始迭代{0}”,i,DateTime.Now.ToLocalTime());
字符串longTaskResult=MrDelay(i);
WriteLine(“在:{1}处完成的迭代{0}结果”,i,longTaskResult);
}
);
开始时间。停止();
WriteLine(“测试用例2:+startTime.passed.TotalSeconds”);
}
延迟处理代码

/// <summary>
    /// Just to slow down the test to 3 seconds before return the data back
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    private static string MrDelay(int id)
    {
        //Delay 3 seconds then return the result
        System.Threading.Thread.Sleep(3000);
        return "ok request id: " + id.ToString() + "  processed time: " + DateTime.Now.ToLocalTime();
    }
//
///在返回数据之前,将测试速度减慢到3秒
/// 
/// 
/// 
专用静态字符串MrDelay(int-id)
{
//延迟3秒,然后返回结果
系统线程线程睡眠(3000);
返回“确定请求id:+id.ToString()+”处理时间:“+DateTime.Now.ToLocalTime()”;
}

对于大众服务代码,您必须首先回答以下问题:最大值应该是多少

例如,使用任务意味着“最大吞吐量”。这意味着您的任务可能会经常被中断,等待某些东西,所以让CPU核心切换到另一个任务以避免浪费时间。每个任务的平均执行时间相对较长,但每个给定时间内处理的任务量却在飞速增长

这里的另一个例子是“最大CPU消耗”。例如,这些员工喜欢处理音频/视频流、大型数学工厂,比如加密等。这样,最有效的方法是每个备用CPU核心有一个线程/任务,而不是更多(因为切换到另一个线程会花费额外的CPU工作)。与前一个示例相反,这里我们在给定时间内处理的平均任务量相对较低。但由于中断最少,平均执行时间尽可能短


当然,在实际操作中,你有一些东西介于这两个最大值之间。当然,您必须更多地了解哪些因素会影响您的CPU(内核调用、缓存污染、错误共享、数据竞争等等)。您可以从《无bug兔子》中的精彩文章开始:

感谢您的提示,我提出了另一个使用多线程的解决方案。此应用程序将在桌面应用程序上使用,因此这是可以接受的。我能够在3秒内使用线程处理200个或更多任务,而不是100个任务处理30秒以上

  static void Main(string[] args)
    {
        #region MyRegion
        for (int i = 0; i < 200; i++)
        {
            //Create thread
            Thread thread = new Thread(() => DoBigJobThread(i));
            thread.Start();
        }
        #endregion
        //Slow  down to show screen
        System.Threading.Thread.Sleep(3000000);
    }

    static void DoBigJobThread(int id)
    {
        Console.WriteLine(MrDelaySimple(id));
    }

    private static string MrDelaySimple(int id)
    {
        //Delay 3 seconds
        System.Threading.Thread.Sleep(3000);
        return "ok request id: " + id.ToString() + "  processed time: " + DateTime.Now.ToLocalTime();
    }
static void Main(字符串[]args)
{
#区域MyRegion
对于(int i=0;i<200;i++)
{
//创建线程
线程线程=新线程(()=>DoBigJobThread(i));
thread.Start();
}
#端区
//放慢速度以显示屏幕
系统线程线程睡眠(3000000);
}
静态无效DoBigJobThread(内部id)
{
Console.WriteLine(MrDelaySimple(id));
}
私有静态字符串MrDelaySimple(int-id)
{
//延迟3秒
系统线程线程睡眠(3000);
返回“确定请求id:+id.ToString()+”处理时间:“+DateTime.Now.ToLocalTime()”;
}

StartNew和
Parallel.For
都是专门为CPU受限的工作而设计的。如果您实际上没有CPU绑定的工作要做(在您的示例中,您没有这样做),它们将无法有效地工作。如果要创建一个将在3秒内完成的任务,请使用
task.Delay
。如果要加速,可以删除所有
线程。Sleeps
!你让工人睡觉,然后想知道他们为什么不工作!另外,做一些数学。你有100个任务。每个任务需要3秒的工作时间。您有四个核心,因此四个工人可以同时运行。每个核心有25个任务,所以大约需要75秒。你在21世纪就完成了任务,那你为什么要抱怨呢?正如Servy所说,这里的要点是:如果你在做CPU限制的工作,那么你的测试实际上需要强调CPU,而不是睡眠,这样任务并行库就可以有效地调度核心。如果您正在执行IO绑定的工作,那么您的测试应该将所有内容保持在一个线程上,并通过将等待放在正确的位置让编译器担心控制流。你已经做了一个示例程序,它做的每件事都是完全错误的,因此得到垃圾结果也就不足为奇了