为什么线程比我的情况下的任务更快

时间:2017-04-14 18:56:40

标签: c# multithreading asynchronous

我正在学习任务和异步方法。 但是为什么线程如何比我的例子中的任务更快。 看起来async方法没有并发运行,但我的线程肯定是并发运行的。

以下是任务的代码。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ConsoleApplication25
{
    using System.Diagnostics;
    using System.Threading;

    class Program
    {
        static void Main(string[] args)
        {
            var watch = Stopwatch.StartNew();
            watch.Start();
            Task.Run(
                async () =>
                    {
                        var ts = new CancellationTokenSource();
                        CancellationToken ct = ts.Token;

                        List<Task> myTasks = new List<Task>();

                        try
                        {
                            for (int i = 0; i < 10; i++)
                            {
                                myTasks.Add(Print(i, ts));
                            }

                           await Task.WhenAll(myTasks);
                           // Task.WaitAll(myTasks.ToArray());
                        }
                        catch (OperationCanceledException ex1)
                        {
                            Console.Write("here" + ex1);
                        }
                        catch (Exception ex2)
                        {
                            Console.Write("bye" + ex2);
                        }


                    }).GetAwaiter().GetResult();


            watch.Stop();
            Console.WriteLine("total tasks = " + watch.ElapsedMilliseconds );


            var watch2 = Stopwatch.StartNew();
            watch2.Start();

            List<Thread> ThreadList = new List<Thread>();
            for (int i = 0; i < 10; i++)
            {
                Thread newThread = new Thread(ThreadPrint);
                ThreadList.Add(newThread);
                newThread.Start(i);
            }

            foreach (var mythread in ThreadList)
            {
                mythread.Join();
            }

            watch2.Stop();
            Console.WriteLine("total thread= " + watch2.ElapsedMilliseconds);
        }

        public static async Task Print(int id, CancellationTokenSource ts)
        {
            var watch = Stopwatch.StartNew();
            watch.Start();

            int counter = 0;

            while (true)
            {
                counter ++;
             //   Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "Loop " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
                if (counter == 200000000)
                {

                    watch.Stop();
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "EXIT " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
                    break;

                }
             //   Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "here it is " + id + ":::::" + "count = " + counter);
            }
        }

        public static void ThreadPrint(object id)
        {

            var watch = Stopwatch.StartNew();
            watch.Start();

            int counter = 0;

            while (true)
            {
                //Thread.Sleep(100);
                counter++;
                //   Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "Loop " + id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
                if (counter == 200000000)
                {

                    watch.Stop();
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "EXIT " + (int)id + ":::::" + "count = " + counter + "last =" + watch.ElapsedMilliseconds);
                    break;
                }
                //   Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "here it is " + id + ":::::" + "count = " + counter);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的代码不正确

您的Print方法实际上是同步的。

因此,如果是任务,您可以创建单个任务并按顺序运行Print调用。

正确的方法是将调用包装到每个Print而不是整个循环。

myTasks.Add(Task.Run(()=>Print(i, ts));