c task执行线程异步操作

合集下载

C#线程学习笔记七:Task详细用法

C#线程学习笔记七:Task详细用法

C#线程学习笔记七:Task详细⽤法⼀、Task类简介Task类是在.NET Framework 4.0中提供的新功能,主要⽤于异步操作的控制。

它⽐Thread和ThreadPool提供了更为强⼤的功能,并且更⽅便使⽤。

Task和Task<TResult>类:前者接收的是Action委托类型;后者接收的是Func<TResult>委托类型。

任务Task和线程Thread的区别:1、任务是架构在线程之上。

也就是说任务最终还是要抛给线程去执⾏,它们都是在同⼀命名空间System.Threading下。

2、任务跟线程并不是⼀对⼀的关系。

⽐如说开启10个任务并不⼀定会开启10个线程,因为使⽤Task开启新任务时,是从线程池中调⽤线程,这点与ThreadPool.QueueUserWorkItem类似。

⼆、Task的创建2.1创建⽅式1:调⽤构造函数class Program{static void Main(string[] args){#region⼯作者线程:使⽤任务实现异步ThreadPool.SetMaxThreads(1000, 1000);PrintMessage("Main thread start.");//调⽤构造函数创建Task对象Task<int> task = new Task<int>(n => AsyncMethod((int)n), 10);//启动任务task.Start();//等待任务完成task.Wait();Console.WriteLine("The method result is: " + task.Result);Console.ReadLine();#endregion}///<summary>///打印线程池信息///</summary>///<param name="data"></param>private static void PrintMessage(string data){//获得线程池中可⽤的⼯作者线程数量及I/O线程数量ThreadPool.GetAvailableThreads(out int workThreadNumber, out int ioThreadNumber);Console.WriteLine("{0}\n CurrentThreadId is:{1}\n CurrentThread is background:{2}\n WorkerThreadNumber is:{3}\n IOThreadNumbers is:{4}\n",data,Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsBackground.ToString(),workThreadNumber.ToString(),ioThreadNumber.ToString());}///<summary>///异步⽅法///</summary>///<param name="n"></param>///<returns></returns>private static int AsyncMethod(int n){Thread.Sleep(1000);PrintMessage("Asynchoronous method.");int sum = 0;for (int i = 1; i < n; i++){//运算溢出检查checked{sum += i;}}return sum;}}View Code2.2创建⽅式2:任务⼯⼚class Program{static void Main(string[] args){#region⼯作者线程:使⽤任务⼯⼚实现异步////⽆参⽆返回值//ThreadPool.SetMaxThreads(1000, 1000);//Task.Factory.StartNew(() => PrintMessage("Main thread."));//Console.Read();//有参有返回值ThreadPool.SetMaxThreads(1000, 1000);PrintMessage("Main thread start.");var task = Task.Factory.StartNew(n => AsyncMethod((int)n), 10);//等待任务完成task.Wait();Console.WriteLine("The method result is: " + task.Result);Console.ReadLine();#endregion}///<summary>///打印线程池信息///</summary>///<param name="data"></param>private static void PrintMessage(string data){//获得线程池中可⽤的⼯作者线程数量及I/O线程数量ThreadPool.GetAvailableThreads(out int workThreadNumber, out int ioThreadNumber);Console.WriteLine("{0}\n CurrentThreadId is:{1}\n CurrentThread is background:{2}\n WorkerThreadNumber is:{3}\n IOThreadNumbers is:{4}\n", data,Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsBackground.ToString(),workThreadNumber.ToString(),ioThreadNumber.ToString());}///<summary>///异步⽅法///</summary>///<param name="n"></param>///<returns></returns>private static int AsyncMethod(int n){Thread.Sleep(1000);PrintMessage("Asynchoronous method.");int sum = 0;for (int i = 1; i < n; i++){//运算溢出检查checked{sum += i;}}return sum;}}View Code2.3创建⽅式3:Run⽅法class Program{static void Main(string[] args){#region⼯作者线程:使⽤Task.Run实现异步ThreadPool.SetMaxThreads(1000, 1000);PrintMessage("Main thread start.");var task = Task.Run(() => AsyncMethod(10));//等待任务完成task.Wait();Console.WriteLine("The method result is: " + task.Result);Console.ReadLine();#endregion}///<summary>///打印线程池信息///</summary>///<param name="data"></param>private static void PrintMessage(string data){//获得线程池中可⽤的⼯作者线程数量及I/O线程数量ThreadPool.GetAvailableThreads(out int workThreadNumber, out int ioThreadNumber);Console.WriteLine("{0}\n CurrentThreadId is:{1}\n CurrentThread is background:{2}\n WorkerThreadNumber is:{3}\n IOThreadNumbers is:{4}\n", data,Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsBackground.ToString(),workThreadNumber.ToString(),ioThreadNumber.ToString());}///<summary>///异步⽅法///</summary>///<param name="n"></param>///<returns></returns>private static int AsyncMethod(int n){Thread.Sleep(1000);PrintMessage("Asynchoronous method.");int sum = 0;for (int i = 1; i < n; i++){//运算溢出检查checked{sum += i;}}return sum;}}View Code三、Task的简略⽣命周期可通过Status属性获取。

c语言同步异步处理

c语言同步异步处理

c语言同步异步处理英文回答:Synchronous and asynchronous processing are two different approaches to handling tasks in C programming.Synchronous processing refers to a method where tasks are executed one after another, in a sequential manner. In other words, the program waits for each task to complete before moving on to the next one. This can be useful when the order of execution is important, or when tasks depend on the results of previous tasks. However, synchronous processing can also be time-consuming, as the program has to wait for each task to finish before proceeding.On the other hand, asynchronous processing allows tasks to run concurrently, without waiting for each other to complete. This means that the program can initiate multiple tasks and continue with its execution without blocking. Asynchronous processing is often used when tasks can beexecuted independently and when the order of execution is not critical. It can improve efficiency and performance, especially in situations where there are long-running tasks or when tasks involve waiting for external resources.To implement synchronous processing in C, you can use functions that block until a task is completed, such as the sleep() function or blocking I/O operations. These functions pause the execution of the program until the task is finished.In contrast, asynchronous processing in C can be achieved by using non-blocking I/O operations or by implementing event-driven programming using libraries like libevent or libuv. These libraries allow you to handle multiple tasks concurrently by registering callbacks or event handlers for specific events.中文回答:同步和异步处理是C编程中处理任务的两种不同方法。

C#异步和多线程以及THREAD、THREADPOOL、TASK区别和使用方法

C#异步和多线程以及THREAD、THREADPOOL、TASK区别和使用方法

C#异步和多线程以及THREAD、THREADPOOL、TASK区别和使⽤⽅法本⽂的⽬的是为了让⼤家了解什么是异步?什么是多线程?如何实现多线程?对于当前C#当中三种实现多线程的⽅法如何实现和使⽤?什么情景下选⽤哪⼀技术更好?第⼀部分主要介绍在C#中异步(async/await)和多线程的区别,以及async/await使⽤⽅法。

第⼆部分主要介绍在C#多线程当中Thread、ThreadPool、Task区别和使⽤⽅法。

-------------------------------------------------------------------------------------------------------------------------async/await这⾥的异步只是⼀种编程模式,⼀个编程接⼝设计为异步的,⼤多数时候都是为了灵活地处理并发流程需求的,对于async/await⽤法请看以下代码:static void Main(string[] args){_ = Async1();Console.WriteLine("...............按任意键退出");Console.ReadKey();}static async Task Async1(){Console.WriteLine("异步开始");var r = await Async2();var x = await Async3(r);Console.WriteLine("结果是 {0}", r + x);}static async Task<int> Async2(){await Task.Delay(1000);//⼀种异步延迟⽅法return 100;}static async Task<int> Async3(int x){await Task.Delay(1000);return x % 7;}执⾏结果:使⽤async关键字修饰的⽅法为异步⽅法,async关键字要和await关键字⼀同使⽤才会⽣效。

C#多线程和异步(二)——Task和asyncawait详解

C#多线程和异步(二)——Task和asyncawait详解

C#多线程和异步(⼆)——Task和asyncawait详解⼀、什么是异步 同步和异步主要⽤于修饰⽅法。

当⼀个⽅法被调⽤时,调⽤者需要等待该⽅法执⾏完毕并返回才能继续执⾏,我们称这个⽅法是同步⽅法;当⼀个⽅法被调⽤时⽴即返回,并获取⼀个线程执⾏该⽅法内部的业务,调⽤者不⽤等待该⽅法执⾏完毕,我们称这个⽅法为异步⽅法。

异步的好处在于⾮阻塞(调⽤线程不会暂停执⾏去等待⼦线程完成),因此我们把⼀些不需要⽴即使⽤结果、较耗时的任务设为异步执⾏,可以提⾼程序的运⾏效率。

net4.0在ThreadPool的基础上推出了Task类,微软极⼒推荐使⽤Task来执⾏异步任务,现在C#类库中的异步⽅法基本都⽤到了Task;net5.0推出了async/await,让异步编程更为⽅便。

本篇主要介绍Task、async/await相关的内容,其他异步操作的⽅式会在下⼀篇介绍。

⼆、Task介绍 Task是在ThreadPool的基础上推出的,我们简单了解下ThreadPool。

ThreadPool中有若⼲数量的线程,如果有任务需要处理时,会从线程池中获取⼀个空闲的线程来执⾏任务,任务执⾏完毕后线程不会销毁,⽽是被线程池回收以供后续任务使⽤。

当线程池中所有的线程都在忙碌时,⼜有新任务要处理时,线程池才会新建⼀个线程来处理该任务,如果线程数量达到设置的最⼤值,任务会排队,等待其他任务释放线程后再执⾏。

线程池能减少线程的创建,节省开销,看⼀个ThreadPool的栗⼦吧static void Main(string[] args){for (int i = 1; i <=10; i++){//ThreadPool执⾏任务ThreadPool.QueueUserWorkItem(new WaitCallback((obj) => {Console.WriteLine($"第{obj}个执⾏任务");}),i);}Console.ReadKey();} 上边的代码通过ThreadPool执⾏了10个任务,执⾏结果为: ThreadPool相对于Thread来说可以减少线程的创建,有效减⼩系统开销;但是ThreadPool不能控制线程的执⾏顺序,我们也不能获取线程池内线程取消/异常/完成的通知,即我们不能有效监控和控制线程池中的线程。

C语言异步编程详解

C语言异步编程详解

C语言异步编程详解异步编程是一种在计算机科学中常用的编程模式,它允许同时执行多个任务,提高程序的并发性和响应速度。

C语言作为一种通用的高级编程语言,也有自己的异步编程方式。

本文将详细介绍C语言中的异步编程方法和技巧。

一、异步编程的概念和优势异步编程是一种非阻塞式的编程模式,意味着程序在等待某个任务完成时不会被阻塞,而是会继续执行其他任务。

这种方式可以提高程序的效率和性能,特别适用于处理大量的IO操作和并发任务。

在传统的同步编程中,程序需要等待每个任务完成才能继续执行下一个任务,这样会导致程序的响应速度变慢。

而异步编程则能够在等待某个任务完成的同时,继续执行其他任务,从而提高了程序的并发性和响应速度。

二、C语言中的异步编程方法在C语言中,异步编程可以通过以下几种方法实现。

1. 回调函数(Callback)回调函数是一种常见的异步编程技术,它允许在某个任务完成后自动调用指定的函数。

在C语言中,可以通过注册回调函数的方式实现异步操作。

下面是一个简单的示例,演示了如何使用回调函数实现异步编程:```c#include <stdio.h>void asyncOperation(void (*callback)(void)) { // 模拟异步操作printf("正在执行异步操作...\n");// 模拟异步操作完成后的回调callback();}void callback() {printf("异步操作已完成\n");}int main() {asyncOperation(callback);// 执行其他任务printf("继续执行其他任务...\n");return 0;}```在上面的示例中,`asyncOperation`函数模拟了一个异步操作,在操作完成后调用了注册的回调函数`callback`。

通过这种方式,程序可以在等待异步操作完成时继续执行其他任务,而无需等待异步操作的完成。

c语言task用法

c语言task用法

c语言task用法C语言中的task用法在C语言中,task通常用于管理并发执行的多个任务。

任务是独立执行的代码块,可以同时运行,但彼此之间没有相互干扰。

这种并发执行可以提高程序的效率和响应性。

要在C语言中使用task,你需要使用多线程库,如pthread库。

下面是一些你可以使用task的一般步骤:1. 导入头文件:在你的C程序中,首先需要导入pthread.h头文件。

这个头文件包含了创建和管理task所需的函数和数据类型。

2. 创建task:使用pthread_create函数来创建新的task。

这个函数接受四个参数:指向task标识符的指针、task属性、task函数的指针和传递给task函数的参数。

创建task后,它将在系统中运行并独立执行。

3. 定义task函数:你需要定义一个函数,作为task的入口点。

这个函数将在task启动后执行,并完成你需要并发执行的任务。

4. 等待task完成:你可以使用pthread_join函数等待task的完成。

这个函数将阻塞主线程,直到指定的task结束执行。

5. 终止task:你还可以使用pthread_cancel函数提前终止一个正在执行的task。

这个函数会发送一个信号给指定的task,以请求其提前终止执行。

除了以上提到的基本步骤外,你还可以使用其他pthread库提供的函数来管理和同步task之间的并发执行。

总结:在C语言中,使用task可以实现并发执行任务的能力。

通过使用pthread库,你可以创建、管理和同步多个task。

这样可以提高程序的效率和响应性。

记得始终遵守C语言的语法规范和良好的编码实践,以确保任务的正确执行。

C#多线程实现异步接口

C#多线程实现异步接口

C#多线程实现异步接⼝异步接⼝的声明我们已经了解到,如果⼀个⽅法是异步的,那么这个⽅法的返回值类型是Task<T>,那么接⼝中该如何规定异步⽅法呢?⼀样的,如果接⼝中的⽅法是异步的,那么规定⽅法的返回值类型是Task<T>即可,看下⾯的代码:interface ITest{/// <summary>/// ⽅法的返回类型是Task<T>/// </summary>/// <returns></returns>Task<string> GetAsync();}注意:⽅法的前⾯不能添加async标注。

因为从语法上来讲,接⼝只能定义⾏为,不能定义实现,如果标注为async,就属于实现了。

我们在⽅法前⾯标注async,看看是什么效果:我们看到,⽅法直接就报错了。

⽽接⼝的实现类中的⽅法可以标注为async,也可以不标注为async,看下⾯的代码:/// <summary>/// 定义接⼝/// </summary>interface ITest{/// <summary>/// ⽅法的返回类型是Task<T>/// </summary>/// <returns></returns>///不能标注为asyncTask<string> GetAsync();}public class Test : ITest{/// <summary>/// ⽅法不标注为async 返回⼀个Task<string>类型/// </summary>/// <returns></returns>//public Task<string> GetAsync()//{// return Task.Run<string>(() =>// {// return "2";// });//}/// <summary>/// ⽅法标注为async 直接返回⼀个string类型/// </summary>/// <returns></returns>public async Task<string> GetAsync(){return "3";}}到此这篇关于C#多线程实现异步接⼝的⽂章就介绍到这了。

c语言同步和异步

c语言同步和异步

c语言同步和异步在编程领域中,同步和异步是很常见的概念。

这两个概念涉及到程序执行的方式和资源利用的方式。

了解这两个概念对于写出高效的程序以及优化程序性能至关重要。

本文将详细介绍C语言中的同步和异步,帮助读者理解并正确应用它们。

首先,我们来了解同步(Synchronous)编程。

同步编程在程序执行过程中,代码会顺序地执行,即每个操作都会等待前一个操作完成后再执行。

这意味着程序会按照顺序逐步执行,而不会并行执行。

当执行一个操作时,它会阻塞后续操作的执行,直到该操作完成并返回结果。

这种方式适用于简单的、线性的任务。

同步编程简单易懂,但对于大规模或者复杂的任务来说效率并不高。

例如,如果一个操作需要花费很长的时间才能完成,那么后续的操作就必须等待,导致程序执行的效率低下。

同时,如果一个操作发生错误或异常,整个程序可能会中断或进入无限等待状态。

为了解决同步编程的问题,我们引入了异步(Asynchronous)编程。

异步编程在执行过程中,代码会同时进行多个操作,而不会阻塞其他操作的执行。

相比于同步编程,异步编程能够更充分地利用计算资源,提高程序的执行效率。

在C语言中,使用异步编程的一种方式是利用回调函数(Callback Function)。

通过使用回调函数,我们可以在操作完成后异步地执行任务。

在执行一个需要等待时间的操作时,C语言会立即返回并继续执行后续的代码,而不会等待操作完成。

当操作完成后,系统会调用事先指定的回调函数,执行后续任务。

这样就实现了非阻塞的异步执行。

异步编程带来的一个挑战是对于程序流程的控制。

由于异步操作的执行顺序不确定,我们不能简单地通过顺序编写代码来控制程序的执行流程。

为了解决这个问题,我们可以使用事件驱动编程(Event-driven Programming)的方式。

通过定义事件处理函数,在某个异步操作完成时触发相应的事件,再执行相应的操作。

这样可以实现程序的灵活控制和协调。

异步编程在处理网络请求、文件读写、图形界面等场景中非常常见。

C#Task任务详解及其使用方式

C#Task任务详解及其使用方式

C#Task任务详解及其使⽤⽅式C#多线程编程笔记(4.3)-Task任务中实现取消选项1.Task类介绍:Task 类的表⽰单个操作不返回⼀个值,通常以异步⽅式执⾏。

Task 对象是⼀个的中⼼思想基于任务的异步模式⾸次引⼊.NET Framework 4 中。

因为由执⾏⼯作 Task 对象通常以异步⽅式执⾏在线程池线程上⽽不是以同步⽅式在主应⽤程序线程,您可以使⽤ Status 属性,以及IsCanceled, ,IsCompleted, ,和 IsFaulted 属性,以确定任务的状态。

⼤多数情况下,lambda 表达式⽤于指定的任务是执⾏的⼯作。

对于返回值的操作,您使⽤ Task 类。

任务Task和线程Thread的区别:1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执⾏。

2、任务跟线程不是⼀对⼀的关系,⽐如开10个任务并不是说会开10个线程,这⼀点任务有点类似线程池,但是任务相⽐线程池有很⼩的开销和精确的控制。

Task和Thread⼀样,位于System.Threading命名空间下!⼀、创建TaskTask 类还提供了构造函数对任务进⾏初始化,但的未计划的执⾏。

出于性能原因, Task.Run 或 TaskFactory.StartNew(⼯⼚创建)⽅法是⽤于创建和计划计算的任务的⾸选的机制,但对于创建和计划必须分开的⽅案,您可以使⽤的构造函数(new⼀个出来),然后调⽤ Task.Start ⽅法来计划任务,以在稍后某个时间执⾏。

//第⼀种创建⽅式,直接实例化:必须⼿动去Startvar task1 = new Task(() =>{//TODO you code});task1.Start();//第⼆种创建⽅式,⼯⼚创建,直接执⾏var task2 = Task.Factory.StartNew(() =>{//TODO you code});⼆、Task的简略⽣命周期:⽅法名说明Created表⽰默认初始化任务,但是“⼯⼚创建的”实例直接跳过。

c语言task 用法 -回复

c语言task 用法 -回复

c语言task 用法-回复标题:C语言Task用法详解:实现高效编程的利器引言:C语言作为一种高效、强大的编程语言,经常被用于开发底层应用,系统软件以及嵌入式系统。

其灵活性和效率使其成为广大开发者的首选。

而在C语言中,Task(任务)是管理和执行并发操作的重要工具。

本文将详细介绍C语言Task的用法,帮助读者深入了解并充分利用这一强大功能。

一、任务的概念与创建任务(Task)是指在多核或单核环境中,能够并发执行的代码片段。

在C语言中,任务可以通过创建线程或进程的方式实现。

在这两种方式中,线程更为常用和广泛,因此本文将主要关注于线程的概念和创建。

要创建一个线程,可以使用C语言提供的pthread库。

以下为创建一个线程的基本步骤:1. 引入pthread库的头文件:c#include <pthread.h>2. 定义线程函数:线程函数是需要并发执行的代码,可以定义为如下格式:cvoid* function_name(void* arg);3. 创建线程:在主函数中使用pthread_create函数来创建线程,创建时需要传入线程的标识符、线程属性和线程函数,具体如下:cint pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);二、任务的同步与互斥在多任务并发执行时,往往存在共享数据的访问问题。

为了保证数据的正确性和一致性,需要采用同步和互斥的机制。

C语言通过信号量、互斥锁和条件变量等机制来实现任务的同步与互斥。

1. 信号量(Semaphore):信号量是用来控制多个任务对共享资源的访问的一种机制。

C语言通过sem_init、sem_wait和sem_post等函数来实现信号量的创建、等待和释放。

2. 互斥锁(Mutex):互斥锁是一种保护共享资源的机制,保证同一时间只能有一个任务对资源进行操作。

Task多线程异步——解决查询慢的问题

Task多线程异步——解决查询慢的问题

Task多线程异步——解决查询慢的问题前⾔报表进⾏查询操作,⽅法是使⽤sql查询或者procedure查询,当时是没有办法在优化sql语句了,然后想到可以将查询结果进⾏拆分,多次查询拼接起来。

然后选⽤task......说真的,task真的帮了⼤忙,⼤⼤缩减了执⾏时间,不过还是要根据需求合理使⽤,毕竟好东西有利⼜有弊1.这⾥给出两种⽅法1.1 Task(Action action) Task构造函数接受的是Action委托1.2Task<TResult>(Func<TResult> continuationFunction) Task<TResult>接受的是Func<TResult>委托2.Task(Action action)举个栗⼦:1static void Main(string[] args)2 {3 Console.WriteLine("多线程开始......" + DateTime.Now + lisecond);4var desc=new AwaitBll().GetAwaitMesg();5 Console.WriteLine(desc.Id+);6 Console.WriteLine("结束......" + DateTime.Now + lisecond);7 Console.ReadLine();8 }9public class AwaitBll10 {11 Model model = new Model();12public Model GetAwaitMesg()13 {14 List<Task> tasks = new List<Task>();15 tasks.Add(new Task(() => GetAwaitId(1)));16 tasks.Add(new Task(() => GetAwaitName("leap")));17foreach (var task in tasks)18 task.Start();19 Task.WaitAll(tasks.ToArray());20return model;21 }22public void GetAwaitId(int id)23 {24 model.Id = id;25 }26public void GetAwaitName(string name)27 {28 = name;29 }30 }3.Task<TResult>(Func<TResult> continuationFunction) 同样举个栗⼦:1static void Main(string[] args)2 {3 Console.WriteLine("多线程开始......" + DateTime.Now + lisecond);4var desc=new AwaitBll().GetAwaitMesg();5foreach (var item in desc)6 {7 Console.WriteLine(item.Id + );8 }9 Console.WriteLine("结束......" + DateTime.Now + lisecond);10 Console.ReadLine();11 }1213public class AwaitBll14 {15public List<Model> GetAwaitMesg()16 {17 Task<List<Model>> list = Task.Run(() => GetAwaitPerson());18 Task<Model> total = Task.Run(() => GetAwaitTotal());19 Task.WaitAll(list, total);20var all = list.Result;21 all.Add(total.Result);22return all;23 }24public List<Model> GetAwaitPerson()25 {26 List<Model> mlist=new List<Model>();27for (var i = 1; i <=10; i++)28 {29 mlist.Add(new Model(i, "leap_" + i));30 }31return mlist;32 }33public Model GetAwaitTotal()34 {35return new Model(0, "合计");36 }37 }这⾥给出简单demo,可以根据⾃⾝需求举⼀反三,原理都是⼀样的。

C#中的Task.Delay()延迟与异步执行返回结果

C#中的Task.Delay()延迟与异步执行返回结果

C#中的Task.Delay()延迟与异步执⾏返回结果1.暂停⼀段时间public static Task ShortDelay(TimeSpan delay){await Task.Delay(delay);Console.WriteLine(string.Format("延迟{0}", delay));}解析:异步编程使⽤async与await关键字,搭配返回Task或其泛型async的存在是为了代码中await的⽣效如果没有返回值,更推荐写为Task,⽽不是voidTask.Delay()是异步编程提供的延迟⽅法,如果你想延迟两秒,可以Task.Delay(2000);当Task.Delay(delay);执⾏后,会异步延迟delay的时间,在延迟的同时,执⾏下⽅的Console当这⾏代码前+await,会等待异步延迟的执⾏结束后,执⾏下⽅的Console2.实现简单的指数退避策略pulic static async Task ToDoRetries(){var nextDelay = TimeSpan.FromSeconds(1);for(int i = 0; i<3; i++){return await DoSometingAsync();nextDelay += nextDelay;await Task.Delay(nextDelat);}}解析:退避策略:防⽌被访问的频繁被阻塞3.实现超时处理private static async Task<string> ToDoAsync(){await Task.Delay(TimeSpan.FromSeconds(3));return "To Do Success!";}public static async Task<string> ToDoWithTimeOut(){var toDoTask = ToDoAsync();var timeOutTask = Task.Delay(TimeSpan.FormSeconds(3));var completedTask = await Task.WhenAny(toDoTask, timeOutTask);if(completedTask == timeOutTask){return "";}return await toDoTask;}解析:Task.WhenAny(toDoTask, timeOutTask);是只要其中有⼀个异步,或者说是任务完成,就返回最费解就是最后最后⼀⾏,toDoTask是⼀个Task,并不是异步⽅法,为什么前⾯还有await,当将await去掉后:断点后发现,toDoTask是⼀个Task类型,其中有id,status等属性,如果在Task类型前+await,获取的是Task类型中Result属性的值出处:===============================================================================================================以下是我⾃⼰在WinConsole程序中的测试:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{class Program{static void Main(string[] args){var t1 = AsyncGetsum();Console.WriteLine(t1.Result); //会阻塞主线程var t = ToDoWithTimeOut();Console.WriteLine(t.Result); //会阻塞主线程Console.ReadKey();}private static async Task<int> AsyncGetsum(){int sum = 0;for (int i = 0; i <= 100; i++){sum += i;System.Diagnostics.Debug.WriteLine("sum += " + i);await Task.Delay(50);}return sum;}private static async Task<string> ToDoAsync(){await Task.Delay(TimeSpan.FromSeconds(3));return"To Do Success!";}public static async Task<string> ToDoWithTimeOut(){var toDoTask = ToDoAsync();var timeOutTask = Task.Delay(TimeSpan.FromSeconds(2));var completedTask = await Task.WhenAny(toDoTask, timeOutTask);if (completedTask == timeOutTask){return"No";}return await toDoTask;}}}以下是我⾃⼰在WinForm程序中的测试:private async Task<int> AsyncGetsum(){int sum = 0;label3.Text = ("使⽤Task执⾏异步操作." + DateTime.Now.ToString("HH:mm:ss.fff"));for (int i = 0; i <= 100; i++){sum += i;System.Diagnostics.Debug.WriteLine("sum += " + i);await Task.Delay(50);//label4.Text = sum.ToString(); //可以在异步⽅法⾥直接赋值操作}return sum;}private async Task<string> ToDoAsync(){await Task.Delay(TimeSpan.FromSeconds(1));return"To Do Success!";}public async Task<string> ToDoWithTimeOut(){var toDoTask = ToDoAsync();var timeOutTask = Task.Delay(TimeSpan.FromSeconds(2));var completedTask = await Task.WhenAny(toDoTask, timeOutTask);if (completedTask == timeOutTask){return"No";}return await toDoTask;}private async void btTaskTest_Click(object sender, EventArgs e){//Task<string> retStr = ToDoWithTimeOut(); //直接调⽤返回的是Task对象string res = await ToDoWithTimeOut(); //使⽤await 修饰符返回的是Task运⾏的结果值label4.Text = retStr.Result; //会阻塞主线程label4.Text = res;var ret1 = AsyncGetsum();label1.Text = ("主线程执⾏其他处理 :" + DateTime.Now.ToString("HH:mm:ss.fff"));for (int i = 1; i <= 3; i++)System.Threading.Thread.Sleep(400); //模拟主线程阻塞await ret1.ContinueWith((Task<int> s) => //此⾏语句的前⾯加上await则表⽰当前代码块是同步执⾏还是异步执⾏,直接影响该代码块后⾯的代码执⾏时间{int result = ret1.Result; //会阻塞主线程string msg = string.Format("任务执⾏结果:{0} == " + DateTime.Now.ToString("HH:mm:ss.fff"), result);System.Diagnostics.Debug.WriteLine(msg);Comm.UtilityHelper.UpdateUI(label4, msg);});label2.Text = ("Call Main() == " + DateTime.Now.ToString("HH:mm:ss.fff"));}上⾯的代码我都已经加了注释说明了,不懂的可以问,问了估计我也不会回答。

C#线程篇---Task(任务)和线程池不得不说的秘密(5)

C#线程篇---Task(任务)和线程池不得不说的秘密(5)

C#线程篇---Task(任务)和线程池不得不说的秘密(5)在上篇最后⼀个例⼦之后,我们发现了怎么去使⽤线程池,调⽤ThreadPool的QueueUserWorkItem⽅法来发起⼀次异步的、计算限制的操作,例⼦很简单,不是吗? 然⽽,在今天这篇博客中,我们要知道的是,QueueUserWorkItem这个技术存在许多限制。

其中最⼤的问题是没有⼀个内建的机制让你知道操作在什么时候完成,也没有⼀个机制在操作完成是获得⼀个返回值,这些问题使得我们都不敢启⽤这个技术。

Microsoft为了克服这些限制(同时解决其他⼀些问题),引⼊了任务(tasks)的概念。

顺带说⼀下我们得通过System.Threading.Tasks命名空间来使⽤它们。

现在我要说的是,⽤线程池不是调⽤ThreadPool的QueueUserWorkItem⽅法,⽽是⽤任务来做相同的事:1 static void Main(string[] args)2 {3 Console.WriteLine("主线程启动");4 //ThreadPool.QueueUserWorkItem(StartCode,5);5 new Task(StartCode, 5).Start();6 Console.WriteLine("主线程运⾏到此!");7 Thread.Sleep(1000);8 }910 private static void StartCode(object i)11 {12 Console.WriteLine("开始执⾏⼦线程...{0}",i);13 Thread.Sleep(1000);//模拟代码操作14 }15 }嘿,你会发现结果是⼀样的。

再来看看这个是什么:TaskCreationOptions这个类型是⼀个枚举类型,传递⼀些标志来控制Task的执⾏⽅式。

C#异步编程的几种方式

C#异步编程的几种方式

C#异步编程的⼏种⽅式在异步程序中,程序代码不需要严格按照编写时的顺序执⾏为了改善代码性能,有时候需要在⼀个新的线程中运⾏⼀部分代码有时候⽆需创建新的线程,但为了更好的利⽤单个线程的能⼒,需要改变代码的执⾏顺序也就是说:异步编程赋予代码⾮顺序执⾏的能⼒,让程序能够在部分耗时操作的同时,⼲其他的事情⼀、通过委托实现异步如果委托对象在调⽤列表中只有⼀个⽅法(引⽤⽅法),它就可以异步执⾏这个⽅法委托类有 BeginInvoke,EndInvoke ⽅法,可以⽤以下⽅式使⽤:当调⽤ BeginInvoke ⽅法时,它开始在⼀个独⽴线程上执⾏引⽤⽅法,并⽴即返回到原始线程;原始线程可以继续运⾏,⽽引⽤⽅法会在线程池⼤的线程中并⾏执⾏当程序希望获取已完成的异步⽅法的结果时,可以检查 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性,或者调⽤ EndInvoke ⽅法等待委托的完成使⽤这⼀过程有三种标准模式,区别在于:原始线程如何知道发起的线程已经完成⼀直等待到完成模式(wait until done): 原始线程发起异步⽅法并做了⼀些其他处理后,原始线程中断并等待异步⽅法完成后再继续轮询模式(polling): 原始线程定期检查发起的异步⽅法线程是否完成,如果没有则继续做其他事情回调模式(callback): 原始线程⼀直执⾏,⽆需等待,当发起的线程中引⽤⽅法完成后,发起的线程就调⽤回调⽅法,调⽤ EndInvoke 之前处理异步⽅法的结果:1static void Main(string[] args)2 {3 Console.WriteLine("===== 同步调⽤ =====");4 AddDel del = new AddDel(Add);5int result = del.Invoke(11, 89);6 Console.WriteLine("计算结果:" + result);7 Console.WriteLine("继续削铅笔...\n");8 Console.ReadKey();910 Console.WriteLine("===== 异步调⽤ =====");11 IAsyncResult result_1 = del.BeginInvoke(22, 78, null, null);12 Console.WriteLine("继续削铅笔...");13 Console.WriteLine("计算结果:" + del.EndInvoke(result_1));14 Console.ReadKey();1516 Console.WriteLine("\n===== 异步回调 =====");17 del.BeginInvoke(33, 67, new AsyncCallback(AddAsync), "AsyncState:OK");18 Console.WriteLine("继续削铅笔...");19 Console.ReadKey();20 }2122// 委托23public delegate int AddDel(int a, int b);24// 加法计算25static int Add(int a, int b)26 {27 Console.WriteLine("开始计算:" + a + "+" + b);28// 模拟运⾏时间29 Thread.Sleep(2000);30 Console.WriteLine("计算完成!");31return a + b;32 }33// 回调函数34static void AddAsync(IAsyncResult ar)35 {36 AddDel del = ((AsyncResult)ar).AsyncDelegate as AddDel;37 Console.WriteLine("计算结果:" + del.EndInvoke(ar));38 Console.WriteLine(ar.AsyncState);39 }⼆、通过 Task 实现异步Task 类通常是以异步⽅式执⾏的单个操作,更适合在后台完成的⼀些⼩任务由于 Task 对象执⾏的⼯作通常在线程池的线程上异步执⾏,⽽不是在程序主线程上同步执⾏因此可以使⽤ Status 属性,还可以使⽤ IsCancele、IsCompleted 和 IsFaulted 属性来确认任务的状态⼤多数情况下,lambda 表达式⽤于指定的任务是执⾏的⼯作:1static void Main(string[] args)2 {3 Console.WriteLine("主线程正在执⾏业务处理!");4// 创建任务5 Task task = new Task(() =>6 {7 Console.WriteLine("使⽤Task执⾏异步操作:");8for (int i = 0; i <= 10; i++)9 {10 Console.WriteLine("操作执⾏:" + i * 10 + "%");11 Thread.Sleep(100);12 }13 Console.WriteLine("Task异步操作执⾏完成!");14 });15// 启动任务,并安排到当前任务队列线程中执⾏任务16 task.Start();17 Thread.Sleep(500);18 Console.WriteLine("主线程正在执⾏其他业务!");19 Console.ReadKey();20 }三、通过 await/async 实现异步C# 中的 Async 和 Await 关键字是异步编程的核⼼通过这两个关键字,可以使⽤ .NET Framework、.NET Core 或 Windows 运⾏时中的资源,轻松创建异步⽅法(⼏乎与创建同步⽅法⼀样轻松)⽽使⽤ Async 关键字定义的异步⽅法简称为 "异步⽅法":1static void Main(string[] args)2 {3 Console.WriteLine("主线程正在执⾏第⼀项业务!");4 AsyncTest();5 Thread.Sleep(300);6 Console.WriteLine("主线程正在执⾏第⼆项业务!");7 Thread.Sleep(300);8 Console.WriteLine("主线程正在执⾏第三项业务!");9 Thread.Sleep(500);10 Console.WriteLine("主线程正在执⾏最后⼀项业务!");11 Console.ReadKey();12 }1314public static async void AsyncTest()16 Console.WriteLine("开始执⾏异步操作:");17// await 不会开启新的线程18// 需要⾃⼰创建Task,才会真正的去创建线程19//await new Program().AsyncTaskFun();20await Task.Run(() =>21 {22new Program().AsyncTaskFun();23 });24 Console.WriteLine("异步操作执⾏完成!");25 }2627public async Task<int> AsyncTaskFun()28 {29 Console.WriteLine("异步操作正在执⾏:");30for (int i = 1; i <= 10; i++)31 {32 Console.WriteLine("操作执⾏:" + i * 10 + "%");33 Thread.Sleep(100);34 }35return2;36 }四、通过 BackgroundWorker 实现异步有时候我们需要在后台新建⼀个线程默默完成⼀项⼯作,过程中时不时同主线程进⾏通信,这就是 BackgroundWorker 的主要任务BackgroundWorker 类允许在单独的线程上执⾏某个可能导致⽤户界⾯(UI)停⽌响应的耗时操作,并且想要⼀个响应式的UI来反应当前耗时操作的进度 :1public partial class Form1 : Form2 {3// BackgroundWorker实例4 BackgroundWorker bw = new BackgroundWorker();56public Form1()7 {8 InitializeComponent();9 bw.WorkerReportsProgress = true;10 bw.WorkerSupportsCancellation = true;11 bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);12 bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);13 bw.DoWork += new DoWorkEventHandler(bw_DoWork);14 progressBar1.Maximum = 100;15 }16// 进度条变化17private void bw_ProgressChanged(Object sender, ProgressChangedEventArgs e)18 {19 progressBar1.Value = e.ProgressPercentage;20 label1.Text = erState.ToString();21 label1.Update();22 }23// 后台任务完成24private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)25 {26 MessageBox.Show("后台操作执⾏完成!");27 }28// 后台具体任务29private void bw_DoWork(object sender, DoWorkEventArgs e)30 {31 BackgroundWorker bw = sender as BackgroundWorker;32int num = 101;33for (int i = 0; i < num; i++)34 {35if (bw.CancellationPending)36 {37 bw.ReportProgress(i, $"当前进度{i}%, 已停⽌!");38return;39 }40 bw.ReportProgress(i, $"当前进度{i}%");41 Thread.Sleep(100);43return;44 }45// 开始按钮46private void button1_Click(object sender, EventArgs e)47 {48if (bw.IsBusy) return;49 bw.RunWorkerAsync();50 }51// 停⽌按钮52private void button2_Click(object sender, EventArgs e)53 {54 bw.CancelAsync();55 }56 }*** | 以上内容仅为学习参考、学习笔记使⽤ | ***。

c++ 异步执行方法

c++ 异步执行方法

c++ 异步执行方法在C++中,你可以使用多种方法来异步执行代码。

以下是一些常见的方法:1.使用线程(Threads):C++11引入了线程库,你可以使用它来创建和管理线程。

例如:2.c复制代码#include<iostream>#include<thread>void task() {std::cout<< "Task executed in a separate thread\n";}int main() {std::thread t(task); // 创建一个新线程来执行task 函数t.join(); // 等待线程完成return0;}1.使用异步任务(Async Tasks):C++标准库中并没有直接提供异步任务的功能,但你可以使用类似Boost.Asio这样的第三方库,或者创建基于线程的异步任务。

例如,使用Boost.Asio:2.c复制代码#include<iostream>#include<boost/asio.hpp>void task() {std::cout << "Task executed asynchronously\n";}int main() {boost::asio::io_context io;boost::asio::steady_timer t(io,boost::asio::chrono::seconds(5));t.async_wait([](const boost::system::error_code& /*e*/) {task();});io.run(); // 运行I/O上下文,开始等待定时器到期return0;}1.使用协程(Coroutines):C++20引入了协程,这是一种可以让函数在任意地方停止,然后在任意地方恢复执行的语言特性。

C#多线程编程のTask(任务全面解析)

C#多线程编程のTask(任务全面解析)

C#多线程编程のTask(任务全⾯解析)Task是.NET4.0加⼊的,跟线程池ThreadPool的功能类似,⽤Task开启新任务时,会从线程池中调⽤线程,⽽Thread每次实例化都会创建⼀个新的线程。

我们可以说Task是⼀种基于任务的编程模型。

它与thread的主要区别是,它更加⽅便对线程进程调度和获取线程的执⾏结果。

Task类和Task<TResult>类前者接收的是Action委托类型后者接收的是Func<TResult>委托类型任务和线程的区别:1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执⾏。

2、任务跟线程不是⼀对⼀的关系,⽐如开10个任务并不是说会开10个线程,这⼀点任务有点类似线程池,但是任务相⽐线程池有很⼩的开销和精确的控制。

⼀、Task的创建1、直接创建var task1 = new Task(() =>{Console.WriteLine("Begin");System.Threading.Thread.Sleep(5000);Console.WriteLine("Finish");});Console.WriteLine("Before start:" + task1.Status);task1.Start();2、⼯⼚创建Task.Factory.StartNew(()={});3、4.5以后Run运⾏Task.Run(()=>{});4、⼀种⽅便获取返回值的⽅式static void Main(string[] args){var tcs = new TaskCompletionSource<int>();new Thread(() => {Thread.Sleep(5000);int i = Enumerable.Range(1, 100).Sum();tcs.SetResult(i); }).Start();//线程把运⾏计算结果,设为tcs的Result。

C#Task详解

C#Task详解

C#Task详解1、Task的优势ThreadPool相⽐Thread来说具备了很多优势,但是ThreadPool却⼜存在⼀些使⽤上的不⽅便。

⽐如:ThreadPool不⽀持线程的取消、完成、失败通知等交互性操作;ThreadPool不⽀持线程执⾏的先后次序;以往,如果开发者要实现上述功能,需要完成很多额外的⼯作,现在,FCL中提供了⼀个功能更强⼤的概念:Task。

Task在线程池的基础上进⾏了优化,并提供了更多的API。

在FCL4.0中,如果我们要编写多线程程序,Task显然已经优于传统的⽅式。

以下是⼀个简单的任务⽰例:static void Main(string[] args){Task t = new Task(() =>{Console.WriteLine("任务开始⼯作……");//模拟⼯作过程Thread.Sleep(5000);});t.Start();t.ContinueWith((task) =>{Console.WriteLine("任务完成,完成时候的状态为:");Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}",task.IsCanceled, task.IsCompleted, task.IsFaulted);});Console.ReadKey();}2、Task的⽤法2.1 创建任务2.1.1 ⽆返回值的⽅式⽅式1:var t1 = new Task(() => TaskMethod("Task 1"));t1.Start();Task.WaitAll(t1);//等待所有任务结束任务的状态:Start之前为Created,之后为WaitingToRun⽅式2:Task.Run(() => TaskMethod("Task 2"));⽅式3:Task.Factory.StartNew(() => TaskMethod("Task 3")); //直接异步的⽅法//或者var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));Task.WaitAll(t3);//等待所有任务结束任务的状态:Start之前为Running,之后为Runningstatic void Main(string[] args){var t1 = new Task(() => TaskMethod("Task 1"));var t2 = new Task(() => TaskMethod("Task 2"));t2.Start();t1.Start();Task.WaitAll(t1, t2);Task.Run(() => TaskMethod("Task 3"));Task.Factory.StartNew(() => TaskMethod("Task 4"));//标记为长时间运⾏任务,则任务不会使⽤线程池,⽽在单独的线程中运⾏。

c#中task与thread区别及其使用的方法示例

c#中task与thread区别及其使用的方法示例

c#中task 与thread 区别及其使⽤的⽅法⽰例⽬录1.什么是thread2.什么是task3.创建⼀个task 任务有两种模式:1.什么是thread当我们提及多线程的时候会想到thread 和threadpool ,这都是异步操作,threadpool 其实就是thread 的集合,具有很多优势,不过在任务多的时候全局队列会存在竞争⽽消耗资源。

thread 默认为前台线程,主程序必须等线程跑完才会关闭,⽽threadpool 相反。

总结:threadpool 确实⽐thread 性能优,但是两者都没有很好的api 区控制,如果线程执⾏⽆响应就只能等待结束,从⽽诞⽣了task 任务。

2.什么是tasktask 简单地看就是任务,那和thread 有什么区别呢?Task 的背后的实现也是使⽤了线程池线程,但它的性能优于ThreadPoll,因为它使⽤的不是线程池的全局队列,⽽是使⽤的本地队列,使线程之间的资源竞争减少。

同时Task 提供了丰富的API 来管理线程、控制。

但是相对前⾯的两种耗内存,Task 依赖于CPU 对于多核的CPU 性能远超前两者,单核的CPU 三者的性能没什么差别。

3.创建⼀个task 任务有两种模式:1.使⽤factory 创建会直接执⾏,使⽤new 创建不会执⾏,必须等到start 启动之后才执⾏。

12345678910111213public void test(){var testTask = new Task(() =>{Console.WriteLine("task start"); }); testTask.Start(); var factoryTeak = Task.Factory.StartNew(() =>{Console.WriteLine("factory task start"); }); } 2.我们来看看task 的⽣命周期123456789101112v ar testTask = new Task(() => {Console.WriteLine("task start");System.Threading.Thread.Sleep(2000);}); Console.WriteLine(testTask.Status); testTask.Start();Console.WriteLine(testTask.Status);Console.WriteLine(testTask.Status);testTask.Wait(); Console.WriteLine(testTask.Status); Console.WriteLine(testTask.Status);13输出结果:Createdtask startRunningRunningRanToCompletionRanToCompletion可以看出task 确实是异步执⾏,并且wait 很好地控制了task 。

彻底搞懂C#异步编程async和await的原理

彻底搞懂C#异步编程async和await的原理

彻底搞懂C#异步编程async和await的原理1.前提熟练掌握Task并⾏编程。

2.⽤Task并⾏解释async和await异步因为控制台有多线程操作的优化,因此这⾥选择winform来做⽰例。

测试代码如下所⽰:有三个textbox,⼀个buttonusing System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace TestAsyncAwait{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Button1_Click(object sender, EventArgs e){TestAsync();textBox3.Text = "333";}private async void TestAsync(){//Thread.Sleep(5000);//依然阻塞await Task.Run(() =>{Thread.Sleep(2000);this.Invoke((EventHandler)delegate { textBox1.Text = "1"; });Thread.Sleep(2000);});this.Invoke((EventHandler)delegate { textBox2.Text = "22"; });}}}显⽰的顺序是:333,1,22如果在设置textbox显⽰内容之前,通过Thread.CurrentThread.ManagedThreadId属性来获取当前线程ID。

c语言异步回调函数

c语言异步回调函数

c语言异步回调函数C语言异步回调函数在C语言中,异步回调函数是一种常见的编程模式。

它允许程序在进行耗时的操作时,不阻塞主线程的执行,而是通过回调函数在操作完成后通知主线程继续执行其他任务。

异步回调函数的实现可以提高程序的性能和响应速度,特别适用于处理网络请求、文件读写、数据库查询等需要等待耗时操作的场景。

异步回调函数的基本原理是将任务的执行和结果的处理分离开来,使得任务可以在后台线程或其他进程中执行,而主线程可以继续执行其他任务。

当任务完成后,通过回调函数将结果传递给主线程进行处理。

这种机制可以避免阻塞主线程,提高程序的并发性和响应速度。

在C语言中实现异步回调函数通常需要以下几个步骤:1. 定义回调函数:首先需要定义一个函数,作为异步任务完成后的回调函数。

回调函数的参数根据具体情况而定,可以包含任务的结果或状态信息。

2. 注册回调函数:将定义好的回调函数注册到异步任务中,以便在任务完成后调用。

3. 执行异步任务:启动异步任务的执行,任务可以在后台线程或其他进程中执行。

在任务完成后,会调用注册的回调函数并传递相应的参数。

4. 处理回调结果:在回调函数中对任务的结果进行处理。

根据具体需求,可以更新UI界面、发送通知、保存数据等。

下面是一个简单的示例,展示了如何在C语言中使用异步回调函数:```c#include <stdio.h>// 定义回调函数void callback(int result) {printf("任务执行完成,结果为:%d\n", result);}// 异步任务void asyncTask(void (*callback)(int)) {// 模拟任务的耗时操作for (int i = 0; i < 1000000000; i++) {// do something}// 任务完成后调用回调函数callback(100);}int main() {printf("开始执行异步任务\n");// 注册回调函数asyncTask(callback);printf("异步任务已启动\n");// 继续执行其他任务// ...return 0;}```在上述示例中,我们定义了一个异步任务`asyncTask`,它模拟了一个耗时操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

c task执行线程异步操作在C#4.0之前需要执行一个复杂的异步操作时,只能使用CLR线程池技术来执行一个任务。

线程池执行异步任务时,不知道任务何时完成,以及任务的在任务完成后不能获取到返回值。

但是在C#4.0中引人了一个的任务(System.Threading.Tasks命名空间的类型)机制来解决异步操作完成时间和完成后返回值的问题。

1.使用Task类创建并执行简单任务通过使用Task的构造函数来创建任务,并调用Start方法来启动任务并执行异步操作。

创建任务时,必须传递一个Action或Action&lt;Object&gt;类型的委托回调方法,可以选择的传递任务执行时说需要的数据对象等。

Task类的构造函数如下:public Task(Action action);public Task(Action&lt;object&gt; action, object state);public Task(Action action, CancellationToken cancellationToken);public Task(Action action, TaskCreationOptions creationOptions);public Task(Action&lt;object&gt; action, object state, CancellationToken cancellationToken);public Task(Action&lt;object&gt; action, object state, TaskCreationOptions creationOptions);public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions);public Task(Action&lt;object&gt; action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);示例代码:1: static void Main(string[] args)2: {3: Console.WriteLine("主线程执行业务处理.");4: //创建任务5: Task task = new Task(() =&gt; {6: Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");7: for (int i = 0; i &lt; 10; i++)8: {9: Console.WriteLine(i);10: }11: });12: //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)13: task.Start();14: Console.WriteLine("主线程执行其他处理");15: //主线程挂起1000毫秒,等待任务的完成。

16: Thread.Sleep(1000);17: }任务调度结果:2.等待任务的完成并获取返回值使用任务执行异步操作时,最主要的是要后的任务完成时的返回值。

在任务类中有一个实例方法Wait(有许多重载版本)他能等待任务的完成,我们也可以通过Task类的派生类Task&lt;TResult&gt;创建一个异步任务,并指定任务完成时返回值的类型,这样可以通过Task&lt;TResult&gt;的实例对象获取到任务完成后的返回值。

创建一个异步任务并执行0到100求和操作返回最后的计算结果,示例代码:1: static void TaskWait() {2: //创建任务3: Task&lt;int&gt; task = newTask&lt;int&gt;(() =&gt;4: {5: int sum = 0;6: Console.WriteLine("使用Task执行异步操作.");7: for (int i = 0; i &lt; 100; i++)8: {9: sum+=i;10: }11: return sum;12: });13: //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)14: task.Start();15:16: Console.WriteLine("主线程执行其他处理");17: //等待任务的完成执行过程。

18: task.Wait();19: //获得任务的执行结果20: Console.WriteLine("任务执行结果:{0}", task.Result.ToString());21: }执行结果:Task类还有一些静态方法,WaitAll用于等待提供的所有System.Threading.Tasks.Task 对象完成执行过程和Wait用于等待提供的任一个System.Threading.Tasks.Task 对象完成执行过程,这两个方法都有一些重载版本。

//等待所有任务完成public static void WaitAll(params Task[] tasks);//等待任意一个任务完成public static int WaitAny(params Task[] tasks);3.使用ContinueWith方法在任务完成时启动一个新任务在使用能够Task类的Wait方法等待一个任务时或派生类的Result属性获得任务执行结果都有可能阻塞线程,为了解决这个问题可以使用ContinueWith方法,他能在一个任务完成时自动启动一个新的任务来处理执行结果。

示例代码:1: static void TaskContinueWith()2: {3: //创建一个任务4: Task&lt;int&gt; task = newTask&lt;int&gt;(() =&gt;5: {6: int sum = 0;7: Console.WriteLine("使用Task执行异步操作.");8: for (int i = 0; i &lt; 100; i++)9: {10: sum += i;11: }12: return sum;13: });14: //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)15: task.Start();16: Console.WriteLine("主线程执行其他处理");17: //任务完成时执行处理。

18: Task cwt = task.ContinueWith(t =&gt; { 19: Console.WriteLine("任务完成后的执行结果:{0}", t.Result.ToString());20: });21: Thread.Sleep(1000);22: }执行结果:上述示例中任务不是等待完成来显示执行结果,而是使用ContinueWith方法,它能够知道任务在什么时候完成并启动一个新的任务来执行任务完成后的处理。

ContinueWith方法具有一些重载版本,这些重载版本允许指定延续任务需要使用的数据、延续任务的工作方式(System.Threading.Tasks.TaskContinuationOptions的枚举值按位OR运行的结果)等。

4.创建父子任务和任务工厂的使用通过Task类创建的任务是顶级任务,可以通过使用TaskCreationOptions.AttachedToParent 标识把这些任务与创建他的任务相关联,所有子任务全部完成以后父任务才会结束操作。

示例如下:1: static void ParentChildTask() {2: Task&lt;string[]&gt; parent = newTask&lt;string[]&gt;(state =&gt; {3: Console.WriteLine(state);4: string[] result=new string[2];5: //创建并启动子任务6: new Task(() =&gt; { result[0]= "我是子任务1。

"; },TaskCreationOptions.AttachedToParent).Start();7: new Task(() =&gt; { result[1] = "我是子任务2。

"; },TaskCreationOptions.AttachedToParent).Start();8: return result;9: },"我是父任务,并在我的处理过程中创建多个子任务,所有子任务完成以后我才会结束执行。

"); 10: //任务处理完成后执行的操作11: parent.ContinueWith(t =&gt; {12: Array.ForEach(t.Result,r=&gt;Console.WriteLine(r));13: });14: //启动父任务15: parent.Start();16: Console.Read();17: }执行结果:如果需要创建一组具有相同状态的任务时,可以使用TaskFactory类或TaskFactory&lt;TResult&gt;类。

这两个类创建一组任务时可以指定任务的CancellationToken、TaskCreationOptions、TaskContinuationOptions和TaskScheduler默认值。

示例代码:1: static void TaskFactoryApply()2: {3: Task parent = new Task(() =&gt;4: {5: CancellationTokenSource cts = new CancellationTokenSource(5000);6: //创建任务工厂7: TaskFactory tf = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);8: //添加一组具有相同状态的子任务9: Task[] task = new Task[]{10: tf.StartNew(() =&gt;{ Console.WriteLine("我是任务工厂里的第一个任务。

相关文档
最新文档