c#中的异步任务

时间:2016-08-03 05:43:09

标签: c# asynchronous

我有两个任务Job1和Job2及以下是代码。我第一次按顺序运行Job1和Job2,并将秒表输出设为844毫秒。第二次我评论顺序作业并调用并行任务处理并将秒表结果作为11352毫秒。我的假设/期望是我应该得到输出为422(因为844/2)或接近它的某个地方。但结果完全相反。我需要等待两个作业完成,因此我把t1.Wait()和t2.Wait();请帮助我在一半的顺序处理中处理这两个作业。请在下面找到我的代码:

    public ActionResult Index()
    {
        Stopwatch s = new Stopwatch();
        s.Start();

        //Execute 2 jobs in a sequence
        Job1();
        Job2();

        //Execute 2 jobs in parallel
        //var t1 = Task.Run(() => { Job1(); });
        //var t2 = Task.Run(() => { Job2(); });
        //t1.Wait();
        //t2.Wait();

        s.Stop();
        Debug.WriteLine("ElapsedMilliseconds: " + s.ElapsedMilliseconds);
        return View();
    }

    private void Job1()
    {
        for (int i = 0; i < 1000; i++)
        {
            Debug.WriteLine(i);
        }
    }

    private void Job2()
    {
        for (int i = 2000; i < 3000; i++)
        {
            Debug.WriteLine(i);
        }
    }

2 个答案:

答案 0 :(得分:2)

基本上,由于并发期间Debug.WriteLine的开销,第二个示例会变慢。

如果您删除Debug.WriteLine(在引擎盖下调用OutputDebugString),您会注意到一个很大的区别。

MSDN声明:

  

应用程序应发送非常小的调试输出,并为用户提供启用或禁用其使用的方法。要提供更详细的跟踪,请参阅事件跟踪。

正如伊兰在这里所说:

  

&#34; if several threads call OutputDebugString concurrently, they will be synchronized&#34;

你的第一个例子中没有并发性,这可能是它更快的原因。

您也可以考虑转到单一等待。

从此处更改您的代码:

//Execute 2 jobs in parallel
var t1 = Task.Run(() => { Job1(); });
var t2 = Task.Run(() => { Job2(); });
t1.Wait();
t2.Wait();

......对此:

//Execute 2 jobs in parallel
var tasks = new List<Task>();
tasks.Add(Task.Run(() => { Job1(); }));
tasks.Add(Task.Run(() => { Job2(); }));
Task.WaitAll(tasks.ToArray());

答案 1 :(得分:1)

要理解为什么任务与性能无关,但更多的是响应性,你应该阅读

上下文切换: https://en.wikipedia.org/wiki/Context_switch

处理器使用大量周期切换到另一个线程

Mutexes https://en.wikipedia.org/wiki/Mutual_exclusion

每次调用Debug.WriteLine时,Task都会等待,直到另一个Task中的Debug.WriteLine完成并执行上下文切换。