zoukankan      html  css  js  c++  java
  • 【多线程】Task

    介绍

      Task是.NET推出数据任务处理的工作类。位于System.Threading.Tasks命名空间下,通过命名空间也可以看出是个多线程类。

    创建Task:

      Task有很多构造函数,无参有参都有,想了解更多可以去官网查看。这里只介绍经常用的形式。

      第一种:以类的实例化形式进行创建Task。通过实例化一个Task对象,然后Start,这种方式中规中矩。

     Task Task1 = new Task(() => Console.WriteLine("Task")); 
                Task1.Start(); 

    第二种:在实践中通常使用这种简洁形式,这种直接运行了Task不需要在start调用

    Task.Run(() => Console.WriteLine("Task"));

    第三种:通过Task的静态属性创建,然后直接启动。Factory提供对用于创建 Task 和 Task<TResult> 的工厂方法的访问。

         var t1= Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Task");
                    });

     

    StartNew和Run区别

    这两个应用的场景都是一样的,只不过Run是StartNew的再次封装吧,与之相比Run比StartNew自动执行了Unwrap。

    Unwrap:主要的作用就是会把嵌套在Task或者Task<>的结果提取出来。

    判断执行状态:

      通过IsCompleted属性可以查看当前task是否执行完成。

           var t11 = Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Task");
                    });
                    if (t11.IsCompleted)
                    {
                        Console.WriteLine("线程已经完成");
                    }

    等待控制:

      通过WhenAny和WhenAll来控制等待,WhenAny表示任意一个Task完成之后,返回这个Task对象,但是有时候我们需要等待任务的完成,WhenAll表示处理完成之后,返回所有对象实例。例如:

    List<Task<string>> TaskList = new List<Task<string>>() {
                    Task.Factory.StartNew(()=> { return WriteHello(10); },C1.Token),
                    Task.Factory.StartNew(()=> { return WriteHello(20); },C1.Token),
                    Task.Factory.StartNew(()=> { return WriteHello(30); },C1.Token),
                    Task.Factory.StartNew(()=> { return WriteHello(40); },C1.Token)
                };
                //var Reuslt= await Task.WhenAll(TaskList);
                var Reuslt = await Task.WhenAny(TaskList);
                if (Reuslt.IsCompleted)
                {
                    Console.WriteLine("有人完成了");
                }

    等待的时候,要加上async 和 await;

    以上是异步等待,要想实现同步操作使用AwaitAll

             var t1 = Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Task1");
                    });
                    var t2 = Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Task2");
                    });
                    var t3 = Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Task3");
                    });
    
                    //等待并行完成
                    Task.WaitAll(t1, t2, t2, t3);

    此时只有执行完成所有task后才会执行下面的代码。

    死锁问题

    此代码仅作保存研究

    出现死锁:

      #region 并行死锁问题
            public static void ParallelLock()
            {
                var t1 = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Task 1 Start running...");
                    while (true)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                    Console.WriteLine("Task 1 Finished!");
                });
                var t2 = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Task 2 Start running...");
                    System.Threading.Thread.Sleep(2000);
                    Console.WriteLine("Task 2 Finished!");
                });
                Task.WaitAll(t1, t2);
            }
            #endregion
    View Code

    解决办法:

      #region 解决死锁问题
            /// <summary>
            /// 解决死锁问题设置时间
            /// </summary>
            public static void ParallelLockEnd()
            {
                Task[] tasks = new Task[2];
                tasks[0] = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Task 1 Start running...");
                    while (true)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                    Console.WriteLine("Task 1 Finished!");
                });
                tasks[1] = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Task 2 Start running...");
                    System.Threading.Thread.Sleep(2000);
                    Console.WriteLine("Task 2 Finished!");
                });
    
                Task.WaitAll(tasks, 5000);
                for (int i = 0; i < tasks.Length; i++)
                {
                    if (tasks[i].Status != TaskStatus.RanToCompletion)
                    {
                        Console.WriteLine("Task {0} Error!", i + 1);
                    }
                }
                Console.Read();
            }
            #endregion
    View Code
  • 相关阅读:
    CAD输出图至Word
    win7激活工具
    IP地址出现错误
    x%内存可用的问题解决
    第一次来到博客园
    ++x和x++
    标准输入流输出流以及错误流
    关于main函数的参数
    hdu1465 动态规划
    静态变量(static)的特点
  • 原文地址:https://www.cnblogs.com/yanbigfeg/p/9186720.html
Copyright © 2011-2022 走看看