首页 > 其他分享 >任务并行库 (TPL)

任务并行库 (TPL)

时间:2024-02-19 11:57:55浏览次数:26  
标签:Task Console Thread TPL 并行 System Threading 任务 WriteLine

原文链接:https://learn.microsoft.com/zh-cn/dotnet/standard/parallel-programming/task-parallel-library-tpl?redirectedfrom=MSDN

                 https://www.cnblogs.com/zhaotianff/p/10458075.html 

任务并行库 (TPL) 是 System.Threading 和 System.Threading.Tasks 空间中的一组公共类型和 API。 TPL 的目的是通过简化将并行和并发添加到应用程序的过程来提高开发人员的工作效率。 TPL 动态缩放并发的程度以最有效地使用所有可用的处理器。 此外,TPL 还处理工作分区、ThreadPool 上的线程调度、取消支持、状态管理以及其他低级别的细节操作。 通过使用 TPL,你可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能。

使用线程池可以减少并行操作时操作系统资源的开销,然而使用线程池并不简单,从线程池的工作线程中获取结果也并不容易。于是就有了TPL,TPL可被认为是线程池上的又一个抽象层,其对开发人员隐藏了与线程池交互的底层代码,并提供了更细粒度的API。

TPL的核心概念是任务。一个任务代表了一个异步操作,该操作可以通过多种方式运行,可以使用或不使用独立线程运行

如何创建一个任务

使用Task.Run()方法或Task.Factory.StartNew方法。

创建一个控制台应用程序,输入以下代码

class Program
    {
        static void Main(string[] args)
        {
            //使用Task的构造函数
            Task task1 = new Task(Task1Method);
            task1.Start();

            //使用Task.Run
            Task.Run(()=>  Task2Method());

            //使用Task.Factory.StartNew
            Task.Factory.StartNew(Task3Method);

            Console.ReadLine();
        }


        static void Task1Method()
        {
            Console.WriteLine($"task1 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
        }

        static void Task2Method()
        {
            Console.WriteLine($"task2 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
        }

        static void Task3Method()
        {
            Console.WriteLine($"task3 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
        }
    }

  运行结果如下:

 以同步方式运行任务

class Program
    {
        static void Main(string[] args)
        {
            //主线程运行
            TaskMethod("Task1");

            Task task2 = new Task(()=>TaskMethod("Task2"));
            Task task3 = new Task(()=>TaskMethod("Task3"));

            //(同步)主线程运行
            task2.RunSynchronously();

            //(异步)线程池运行
            task3.Start();
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine($"Task {name} is running on a thread id : {System.Threading.Thread.CurrentThread.ManagedThreadId}, " +
                              $"Is thread pool thread: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
            System.Threading.Thread.Sleep(1000);

        }
    }

  运行结果:

 

使用单独线程的任务

如果任务的代码将长时间运行,可以使用TaskCreationOptions.LongRunning来告诉任务创建一个新线程,而不是使用线程池中的线程

示例代码如下

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
            var t1 = new Task(TaskMethod,TaskCreationOptions.LongRunning);
            t1.Start();
        }

        static void TaskMethod()
        {
            Console.WriteLine(System.Threading.Thread.CurrentThread.IsThreadPoolThread);
            Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    }

  运行结果:

 使用任务来执行操作

class Program
    {
        static void Main(string[] args)
        {
            TaskMethod("Task1");//会阻塞主线程,直到耗时操作完成

            Task<int> task = CreateTask("Task 2");
            Console.WriteLine(task.Status);
            task.Start();//启动任务,并不会阻塞主线程,会继续往下执行
            while(!task.IsCompleted)
            {
                Console.WriteLine(task.Status);
                System.Threading.Thread.Sleep(1000);
            }
            Console.WriteLine(task.Status);
            int result = task.Result;
            Console.WriteLine($"Result is : {result}");
        }

        static Task<int> CreateTask(string name)
        {
            return new Task<int>(()=> TaskMethod(name));
        }

        static int TaskMethod(string name)
        {
            Console.WriteLine($"Task {name} is running on a thread id : {System.Threading.Thread.CurrentThread.ManagedThreadId}, Is thread pool thread: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
            //模拟耗时操作
            System.Threading.Thread.Sleep(10000);
            return 0;
        }
    }

  运行结果:

 

组合任务

使用Task< TResult> . ContinueWith方法来创建当另一任务完成时可以执行的延续任务。

当task1执行完成后,把task1返回的结果传递到下一个任务

1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Task<int> task1 = new Task<int>(()=> TaskMethod("Task1",1));
 6              7 
 8             task1.ContinueWith(x => Console.WriteLine($"The task1 result is {x.Result} " + 
 9                 $"Thread id is : {System.Threading.Thread.CurrentThread.ManagedThreadId} " + 
10                 $"Is Thread pool thread : {System.Threading.Thread.CurrentThread.IsThreadPoolThread} "),TaskContinuationOptions.OnlyOnRanToCompletion);
11             //TaskContinuationOptions.OnlyOnRanToCompletion 指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。
12             //更多TaskContinuationOptions可以参考
13             //https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.taskcontinuationoptions?redirectedfrom=MSDN&view=netframework-4.8
14 
15             task1.Start();        
16         }
17 
18         static int TaskMethod(string name,int seconds)
19         {
20             Console.WriteLine($"Task {name} is running on thread id :{System.Threading.Thread.CurrentThread.ManagedThreadId} " + 
21                 $"Is thread pool thread:{System.Threading.Thread.CurrentThread.IsThreadPoolThread} ");
22             System.Threading.Thread.Sleep(TimeSpan.FromSeconds(seconds));
23             return DateTime.Now.Second;
24         }
25     }

   运行结果:

 

标签:Task,Console,Thread,TPL,并行,System,Threading,任务,WriteLine
From: https://www.cnblogs.com/Dongmy/p/18020722

相关文章

  • CentOS上如何配置手动和定时任务自动进行时间同步
    场景Linux(Centos)上使用crontab实现定时任务(定时执行脚本):https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/134576630Winserver上如何配置和开启NTP客户端进行时间同步:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135220767在Centos上如何进行......
  • 自然语言生成任务中的5种采样方法介绍和Pytorch代码实现
    在自然语言生成任务(NLG)中,采样方法是指从生成模型中获取文本输出的一种技术。本文将介绍常用的5中方法并用Pytorch进行实现。束搜索(BeamSearch)是贪婪解码的一种扩展,通过在每个时间步保留多个候选序列来克服贪婪解码的局部最优问题。在每个时间步保留概率最高的前几个候选词语,然......
  • 在涉及恶意软件的任何调查中,寻找持久性点(也称为“自动启动扩展点”或ASEP)是一项经常出
    AutostartcategoriesWhenyoulaunchAutorunsforthefirsttime,allautostartentriesonthesystemaredisplayedinonelonglistontheEverythingtab.As Figure4-8 shows,thedisplayincludesupto19othertabsthatbreakdownthecompletelistint......
  • ThreadPoolTaskExecutor以及通过注解实现异步任务
    ThreadPoolTaskExecutor是Spring框架的线程池,实现方式如下:1//声明一个name为asyncTaskExecutor的线程池bean到容器中2@Bean("asyncTaskExecutor")3publicExecutorgetAsyncExecutor(){4ThreadPoolTaskExecutorthreadPoolExecutor=newThreadPoolTaskExecuto......
  • Win10任务栏图标居中
    win+q键搜索并打开字符映射表点击第五行的空白字符,然后先后点击下方的选择以及复制在桌面新建一个文件夹,然后重命名,将刚才复制的空白字符粘贴进去,如图,这样我们就拥有了一个空白名称的文件夹在任务栏右键→工具栏→新建工具栏→在弹出的对话框中选择刚才新建的空白文件夹,接......
  • matplotlim柱状图
    importnumpyasnpimportmatplotlibmatplotlib.use("TKAgg")importmatplotlib.pyplotaspltd=np.arange(0,10,0.1)datas=np.array([24,10,13,36])subjects=['香蕉','苹果','辣椒','其他']plt.rcParams['font.fa......
  • asp.net 托管服务 后台任务 定时器任务
    托管服务1\1.txtthisisatestfile托管服务1\appsettings.Development.json{"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}}}托管服......
  • 匀加速运动模拟python,(matplotlib)
    importnumpyasnpimportmatplotlibmatplotlib.use("TKAgg")importmatplotlib.pyplotaspltg=9.8s=100ds=0.00001#单位米v0=0.001#m/sv=[v0]t=[ds/v0]t_sum=0ds_num=int(s/ds)x=[]y=[]foriinrange(ds_num+1):ifi==0:continue......
  • celery 5.3.6在windows中运行收到任务不执行
    命令:```celery-Ayour_projectworker--concurrency=2-Peventlet-linfo```1.`celery`:这是用于管理Celery任务的命令行实用程序。2.`-Ajavdb`:指定Celery应用程序实例。3.`worker`:告诉Celery启动一个工作进程。4.`--concurrency=2`:设置工作进程的数量为2。根据......
  • elsa-core自定义Activity创建Bookmark人工任务完成
    //实现一个自定的activity用于人工处理的节点publicclassMyRunTask:Activity<object>{[Input(Description="Thenameofthetaskbeingrequested.")]publicInput<string>TaskName{get;set;}=default!;///<inheritdo......