C# Task.WhenAll Parallel 2 [Debug]

  1. Thread.Sleep and non-Async method will block the thread
  2. await Task.Delay or await Async method will delay the task, but won’t block the thread. The usage of thread will be handed over to other tasks.
  3. By default, the system has 4 threads, but may run 60 tasks in parallel. So the following codes will finish in 1 sec using Task.Delay, but more time using Thread.Sleep.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SystemTasks
{
    class TestTask
    {
        public async static Task TestSyncIth(int ith)
        {
            Console.WriteLine("Start TestSyncIth " + ith);
            Thread.Sleep(1000);       //Could not finish in 1 sec
            //await Task.Delay(1000);      //Finish in 1 sec
            Console.WriteLine("Finish TestSyncIth " + ith);
            return ith;
        }

        public async static Task StartAsync(int option)
        {
            List nums = new List();
            for (int i = 60; i >= 1; --i)
                nums.Add(i);
            var tasks = nums.Select(TestSyncIth).ToArray();
            await Task.WhenAll(tasks);
            foreach(var cur in tasks)
            {
                if (cur.Status == TaskStatus.RanToCompletion)
                {
                    long res = cur.Result;
                    Console.WriteLine("StartAsync " + res);
                }
            }
            Console.WriteLine("All Finish");
        }

        static void Main()
        {
            StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
            return;
        }
    }
}

Several strategies to improve the above non-async codes:

  1. threadpool.setminthreads
  2. Codes like the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SystemTasks
{
    class TestTask
    {
        public async static Task TestSyncIth(int ith)
        {
            Console.WriteLine("Start TestSyncIth " + ith);
            Thread.Sleep(1000);       //Could not finish in 1 sec
            //await Task.Delay(1000);      //Finish in 1 sec
            Console.WriteLine("Finish TestSyncIth " + ith);
            return ith;
        }

        public async static Task StartAsync(int option)
        {
            var tasks = new List>();
            for (int i = 60; i >= 1; --i)
            {
                int cur = i;
                var t = Task.Factory.StartNew(async () => await TestSyncIth(cur), TaskCreationOptions.LongRunning);
                tasks.Add(t.Unwrap());
            }

            await Task.WhenAll(tasks);
            foreach(var cur in tasks)
            {
                if (cur.Status == TaskStatus.RanToCompletion)
                {
                    long res = cur.Result;
                    Console.WriteLine("StartAsync " + res);
                }
            }
            Console.WriteLine("All Finish");
        }

        static void Main()
        {
            StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
            return;
        }
    }
}

A more simpler example:

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

namespace SystemTasks
{
    class TestTask
    {

        public static void TestIth(int ith)
        {
            Console.WriteLine("Start TestSyncIth " + ith);
            Thread.Sleep(2000);
            Console.WriteLine("Finish TestSyncIth " + ith);
        }


        static void Main()
        {
            List list = new List() {1, 2, 3, 4, 5};
            Parallel.ForEach(list, item => TestIth(item));
            return;
        }
    }
}

你可能感兴趣的:(C#)