c# 多线程

多线程

.net 4.0 Task类的出现提高了线程的使用效率

外部变量

        int i = 0;
        //100以内的随机数
        Random r = new Random(100);
        Task t = new Task(() =>
        {
            for (int v = 0; v < 100; v++)
                //最大值50
                i += r.Next(50);
        });
        t.Start();  //开始线程
        t.Wait();   //等待线程结束
        Console.WriteLine("这是执行Task1后等待完成:" + i.ToString());

内部变量

        Random r = new Random(DateTime.Now.Second);
        //Task<T>直接返回结果
        //当调用Result属性时,会自动等待线程结束,等同调用了Wait()。
        Task<int> t = new Task<int>(() =>
        {
            int i = 0;
            for (int v = 0; v < 100; v++)
                i += r.Next(100);
            return i;
        });
        t.Start();  //开始线程
        Console.WriteLine("这是执行Task1后等待完成:" + t.Result.ToString());

ContinueWith

        Random r = new Random(DateTime.Now.Second);
        Task<int> t = new Task<int>(() =>
        {
            int i = 0;
            for (int v = 0; v < 100;v++ )
                i += r.Next(100);
            return i;
        });
        t.ContinueWith((Task<int> task) =>
        {
                Console.WriteLine("这是执行完毕Task1后继续调用Task2:" + task.Result.ToString());    
        });
        t.Start();

ContinueWith链式写法

        Random r = new Random(DateTime.Now.Second);
        Task<int> t = new Task<int>(() =>
        {
            int i = 0;
            for (int v = 0; v < 100; v++)
                i += r.Next(100);
            return i;
        });
        Task t2 = t.ContinueWith((Task<int> task) =>
        {
            Console.WriteLine(task.Result.ToString());
        });
        t2.ContinueWith(task =>
            {
                Console.WriteLine("这是执行完毕Task1后继续调用Task2,Task2后调用Task。");
            });
        t.Start();

Task中断

        CancellationTokenSource cts = new CancellationTokenSource();
        var ctoken = cts.Token;
        Task t1 = new Task(() =>
        {
            for (int v = 0; v < 10; v++)
            {
                if(ctoken.IsCancellationRequested)
                {
                    //第一种写法
                    //这个会抛出异常
                    ctoken.ThrowIfCancellationRequested();

                    //另一种写法
                    //这个不会返回异常,但是获取不到是否是中断还是执行完毕。
                    //return;
                }
                Thread.Sleep(1000);
                Console.WriteLine(v);
            }
        },ctoken);
        t1.Start();
        Thread.Sleep(2000);
        cts.Cancel();
        try
        {
            t1.Wait();
        }
        catch
        {
            if (t1.IsCanceled)
                Console.WriteLine("cancel");
        }
        cts.Dispose();
          中途取消Task执行,Token
         一是正常结束、二是产生例外、三是透过Cancel机制,这三种情况都会反映在Task.Status属性上
         值                                    说明
         Created                                    Task已经建立,但未呼叫Start。
         WaitingForActivation             Task已排入排程,但尚未执行(一般我们建立的Task不会有此状态,只有ContinueWith所产生的Task才会有此状态)。
         WaitingToRun                         Task已排入排程,等待执行中。
         Running                                   Task执行中。
         WaitingForChildrenToComplete    Task正等待子Task結束。
         RanToCompletion                  Task已经正常执行完毕。
         Canceled                                 Task已被取消。
         Faulted                                    Task执行中发生未预期例外。

         除了Status属性外,Task还提供了另外三个属性来判定Task状态。
         属性                     说明
         IsCompleted      Task已经正常执行完毕。
        IsFaulted            Task执行中法生未预期例外。
         IsCanceled         Task已被取消。

StartNew

创建一个新线程,并且直接运行,省略了start的过程

            Task<int> t1 = Task.Factory.StartNew<int>(() =>
                {
                    int total = 0;
                    for (int i = 0; i < 10; i++)
                        total += i;

                    Console.WriteLine("线程运行");                    
                    Thread.Sleep(12000);
                    return total;
                });

ContinueWhenAny

t1,t2中有任何一个task完成都会触发ContinueWhenAny线程,该线程只执行一次

            Task<int> t1 = Task.Factory.StartNew<int>(() =>
                {
                    int total = 0;
                    for (int i = 0; i < 10; i++)
                        total += i;                    
                    Thread.Sleep(12000);
                    return total;
                });

            Task<int> t2 = Task.Factory.StartNew<int>(() =>
                {
                    int total = 0;
                    for (int i = 10; i < 20; i++)
                        total += i;
                    Thread.Sleep(10000);
                    return total;
                });
            Task tfinal = Task.Factory.ContinueWhenAny<int>(
                new Task<int>[] { t1, t2 }, (Task<int> task) =>
                    {
                        if (task.Status == TaskStatus.RanToCompletion)
                        {
                            Console.WriteLine(task.Result);
                        }
                    });

ContinueWhenAll

t1,t2全部执行完毕之后,会触发ContinueWhenAll线程,该线程只执行一次

            Task<int> t1 = Task.Factory.StartNew<int>(() =>
                {
                    int total = 0;
                    for (int i = 0; i < 10; i++)
                        total += i;
                    Thread.Sleep(12000);
                    return total;
                });

            Task<int> t2 = Task.Factory.StartNew<int>(() =>
                {
                    int total = 0;
                    for (int i = 10; i < 20; i++)
                        total += i;
                    Thread.Sleep(10000);
                    return total;
                });
            Task tfinal = Task.Factory.ContinueWhenAll(
                new Task<int>[] { t1, t2 },(Task<int>[] taskCollection) =>
                    {
                        foreach (var task in taskCollection)
                        {
                            Console.WriteLine(task.Result);
                        }
                    });
原文地址:https://www.cnblogs.com/tangpeng97/p/13703829.html