天天看點

Task的阻塞方式和任務延續

//【1】回顧之前使用Thread多個子線程執行時阻塞的方法
static void Method2()
{
    Thread thread1 = new Thread(() =>
    {
        Thread.Sleep(2000);
        Console.WriteLine("Child Thread (1)......");
    });
    Thread thread2 = new Thread(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("Child Thread (2)......");
    });
    thread1.Start();
    thread2.Start();
    //...

    thread1.Join();//讓調用線程阻塞
    thread2.Join();
    //如果有很多的thread,是不是也得有很多的Join?還有,我們隻希望其中一個執行完以後,後面的其他線程就能執行,這個也做不了!

    Console.WriteLine("This is Main Thread!");
}
//【2】Task各種【阻塞】方式(3個)
static void Method3()
{
    Task task1 = new Task(() =>
     {
         Thread.Sleep(1000);
         Console.WriteLine($"Task1子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
     });
    task1.Start();
    Task task2 = new Task(() =>
    {
        Thread.Sleep(2000);
        Console.WriteLine($"Task2子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });
    task2.Start();

    第1種方式:挨個等待和前面一樣
    //task1.Wait();
    //task2.Wait();

    第2種方式:等待所有的任務完成    【推薦】
    //Task.WaitAll(task1, task2);

    //第3種方式:等待任何一個完成即可  【推薦】
    Task.WaitAny(task1, task2);

    Console.WriteLine("主線程開始運作!Time=" + DateTime.Now.ToLongTimeString());
}
//Task任務的延續:WhenAll 希望前面所有任務執行完畢後,再繼續執行後面的線程,和前面相比,既有阻塞,又有延續。
static void Method4()
{
    Task task1 = new Task(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine($"Task1子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });
    task1.Start();
    Task task2 = new Task(() =>
    {
        Thread.Sleep(2000);
        Console.WriteLine($"Task2子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });
    task2.Start();

    //線程的延續(主線程不等待,子線程依次執行,如果你需要主線程也按照子線程的順序來,請你自己把主線程的任務放到延續任務中就可以)
    Task.WhenAll(task1, task2).ContinueWith(task3 =>
     {
         //在這裡可以編寫你需要的業務...

         Console.WriteLine($"Task3子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
     });

    Console.WriteLine("主線程開始運作!Time=" + DateTime.Now.ToLongTimeString());
}
//Task的延續:WhenAny
static void Method5()
{
    Task task1 = new Task(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine($"Task1子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });
    task1.Start();
    Task task2 = new Task(() =>
    {
        Thread.Sleep(2000);
        Console.WriteLine($"Task2子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });
    task2.Start();

    //線程的延續(主線程不等待,子線程任何一個執行完畢,就會執行後面的線程)
    Task.WhenAny(task1, task2).ContinueWith(task3 =>
    {
        //在這裡可以編寫你需要的業務...

        Console.WriteLine($"Task3子線程Id={Thread.CurrentThread.ManagedThreadId}  {DateTime.Now.ToLongTimeString()}");
    });

    Console.WriteLine("主線程開始運作!Time=" + DateTime.Now.ToLongTimeString());
}
           

繼續閱讀