简体   繁体   English

c#中的异步任务

[英]Async Task in c#

I have two tasks Job1 and Job2 and below is the code. 我有两个任务Job1和Job2,下面是代码。 First time I ran Job1 and Job2 in a sequence and got the stopwatch output as 844 milliseconds. 我第一次按顺序运行Job1和Job2,并将秒表输出设为844毫秒。 Second time I commented sequential jobs and called parallel task processing and got the stopwatch result as 11352 milliseconds. 第二次我评论顺序作业并调用并行任务处理并将秒表结果作为11352毫秒。 My assumption/expectation was I should get the output as 422 (because 844/2) or somewhere near to it. 我的假设/期望是我应该得到输出为422(因为844/2)或接近它的某个地方。 But the result is totally opposite. 但结果完全相反。 I need to wait both the jobs to be completed and hence I put t1.Wait() and t2.Wait(); 我需要等待两个作业完成,因此我把t1.Wait()和t2.Wait(); Please help me to process these two jobs in half of sequential processing. 请帮助我在一半的顺序处理中处理这两个作业。 Please find my code below: 请在下面找到我的代码:

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

Essentially your 2nd example is slower due to the overhead of Debug.WriteLine during concurrency. 基本上你的第二个例子是由于在并发期间Debug.WriteLine的开销而变慢。

You'd notice a big difference if you remove Debug.WriteLine (which calls OutputDebugString under the hood). 如果删除Debug.WriteLine (在引擎盖下调用OutputDebugString ),您会注意到一个很大的区别。

MSDN states: MSDN声明:

Applications should send very minimal debug output and provide a way for the user to enable or disable its use. 应用程序应发送非常小的调试输出,并为用户提供启用或禁用其使用的方法。 To provide more detailed tracing, see Event Tracing. 要提供更详细的跟踪,请参阅事件跟踪。

As Eran states here: 正如伊兰所说:

" if several threads call OutputDebugString concurrently, they will be synchronized " . 如果多个线程同时调用OutputDebugString,它们将被同步

There's no concurrency in your first example so that could be a reason why its faster. 您的第一个示例中没有并发性,这可能是其更快的原因。

Also you might want to consider moving to a single wait. 您也可以考虑转向单一等待。

Change your code from this: 从这个改变你的代码:

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

...to this: ......对此:

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

To understand why Tasks have nothing to do with performance but more with responsiveness you should read up on 要理解为什么任务与性能无关,但更多的是响应性,你应该阅读

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

The processor uses lots of cycles to switch to another thread 处理器使用大量周期切换到另一个线程

Mutexes : https://en.wikipedia.org/wiki/Mutual_exclusion 互斥体https//en.wikipedia.org/wiki/Mutual_exclusion

Every time you call Debug.WriteLine the Task waits until Debug.WriteLine in the other Task is done and performs a context switch. 每次调用Debug.WriteLine时,Task都会等待,直到另一个Task中的Debug.WriteLine完成并执行上下文切换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM