首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C# 基础精讲】Task和Task<T>的应用

在本文中,我们将深入探讨 Task 和 Task 的应用,创建、执行、等待到取消和异常处理等方面进行详细讨论,帮助您更好地理解如何在C#应用这些类型。 1....await task; // 等待 Task 完成 int result = await task; // 等待 Task 完成,并获取结果 2.3 使用 Wait 阻塞等待 虽然使用 await...task.Wait(); // 阻塞当前线程,等待任务完成 int result = task.Result; // 阻塞当前线程,等待任务完成,并获取结果 3....= await CalculateAsync(); // 等待操作完成,并获取结果 7....异步任务的嵌套 7.1 嵌套异步方法调用 在异步方法调用另一个异步方法是很常见的,但不会导致阻塞。调用的每个异步方法都会按照异步的方式执行。

35720

浅谈.Net异步编程的前世今生----TPL篇

在第二种方式和第三种方式,被创建的任务会立即开始工作,所以无需显式调用Start方法。...: 代码,我们可以看出,我们给Task传递了两次CancellationTokenSource,一次是任务内执行方法,一次是任务本身构造函数,那么为什么要这样做呢?...; } } } 运行后结果如图所示: 代码实现和运行结果,我们可以看出调用Task的Result属性,会使得当前线程等待直到该任务完成,并将异常传播到当前线程,因此我们可以通过...; } } } 运行后结果如图所示: 我们结果可以看出,在这种情况下,可以直接捕获到底层异常,而无需再访问InnerException属性,原因是TPL模型会直接提取该异常进行处理...在TPL,我们也可以创建另外一系列任务,并使用Task.WhenAny的方式等待这些任务的任何一个执行完成。当有一个任务完成时,会列表移除该任务并继续等待其他任务完成,直到列表为空为止。

42720
您找到你想要的搜索结果了吗?
是的
没有找到

浅谈.Net异步编程的前世今生----异步函数篇(完结)

而在第二个,我们直接使用await对任务进行操作,获取异步执行的结果,同时使用try-catch代码块来捕获可能发生的异常,这和我们编写同步方法的代码风格是一致的,简化了程序编写的复杂度。...: 我们结果可以看出,TPL的后续依赖任务会按照我们的书写顺序依次执行,让人讶异的是await,它并没有并行执行,也是顺序执行的。...否则,在看到await声明时,通常的行为是方法执行到await代码行应立即返回,且剩下的代码会在一个后续操作任务执行。因此等待操作结果时,并没有阻塞程序执行,这是一个异步调用。...造成这种情况的原因是Task.Delay在幕后使用了一个计时器,它的执行过程如下: 1、线程池中获取工作线程,它将等待Task.Delay返回结果; 2、Task.Delay方法启动计时器,并指定一块代码...Task.Run方法则不同,它的执行过程如下: 1、线程池中获取工作线程,并将其阻塞几秒钟; 2、获取第二个工作线程,也将其阻塞几秒钟。

66620

C#语法——await与async的正确打开方式

然后,此时再调用await AsyncTest(),你会神奇的发现,依然没有卵用。。。 Excute方法正常执行,AsyncTest内运行的线程,自己执行自己的。...是用来获取线程返回值的。 这个逻辑是这样的,如果想要获取线程返回结果,就自然要等待线程结束。 运行一下,我们将看下面的结果。...首先,我们定义一个普通函数,他的返回值是一个Task,然后我们得到Task后,运行它,再用await等待这个Task。 于是我们就得到这样的结果。...可以明确的看到,第二组,线程重新回到了主线程1第一组,已经被优化到了线程4。  ...这也是官方为什么只提供了await调用服务的例子,因为,在程序调用,await还是要了解后,再使用,才安全。

1K30

C#并发编程之异步编程(二)

如果需要详细了解控制流,可以异步到MSDN查看。 下图及其描述摘自MSDN: ? 关系图中的数值对应于以下步骤。 事件处理程序调用等待 AccessTheWebAsync 异步方法。...字符串结果不是通过按你预期的方式调用 GetStringAsync 所返回的。(记住,该方法已返回步骤 3 的一个任务)。相反,字符串结果存储在表示 getStringTask 方法完成的任务。...await 运算符 getStringTask 检索结果。赋值语句将检索到的结果赋给 urlContents。 当 AccessTheWebAsync 获取字符串结果时,该方法可以计算字符串长度。...在调用方内部(此示例的事件处理程序),处理模式将继续。在等待结果前,调用方可以开展不依赖于 AccessTheWebAsync 结果的其他工作,否则就需等待片刻。...事件处理程序等待 AccessTheWebAsync, AccessTheWebAsync 等待 GetStringAsync。

1.2K20

c#异步编程-Task(一)

个人心得:Task是一个升级版本的Thread的类,它非常的灵活支持取消、阻塞等待、合并多个Task协同操作、编码高效易懂、异常传播、回调传递结果调用方法等。...Task.Run返回一个Task对象,可以使用它来监视其过程 在Task.Run之后,我们没有调用Start,因为该方法创建的是“热”任务(hot task) 可以通过task的构造函数创建“冷”任务(...使用Func委托或兼容的Lambda表达式来调用Task.Run就可以得到Task。 随后,可以通过Result属性来获得返回的结果。...无需调用GetResult,我们可以直接访问task的Result属性。...如果是编写一个库,则不希望出现上述行为,因为开销较大的UI线程切换应该再程序运行离开库的时候只发生一次,不是出现在方法调用之间。

58410

C#5.0新增功能01 异步编程

执行伤害计算的开销可能极大,而且在 UI 线程执行计算有可能使游戏在计算执行过程暂停! 此问题的最佳解决方法是启动一个后台线程,它使用 Task.Run 执行工作,并 await 其结果。...如果你的工作为 I/O 绑定,请使用 async 和 await (不使用 Task.Run)。 不应使用任务并行库 。 相关原因在深入了解异步的文章说明。...// 这使得应用程序能够响应不阻塞UI线程。...这是 .NET 的惯例,以便更轻松区分同步和异步方法。 请注意,未由代码显式调用的某些方法(如事件处理程序或 Web 控制器方法)并不一定适用。...不是… 若要执行此操作 await Task.Wait 或 Task.Result 检索后台任务的结果 await Task.WhenAny Task.WaitAny 等待任何任务完成 await Task.WhenAll

2.3K20

C#多线程(13):任务基础①

目录 多线程编程 多线程编程模式 探究优点 任务操作 两种创建任务的方式 Task.Run() 创建任务 取消任务 父子任务 任务返回结果以及异步获取返回结果 捕获任务异常 全局捕获任务异常 多线程编程...前面,我们学习了三部分的内容: 线程基础:如何创建线程、获取线程信息以及等待线程完成任务; 线程同步:探究各种方式实现进程和线程同步,以及线程等待; 线程池:线程池的优点和使用方法,基于任务的操作; 这篇开始探究任务和异步...如果父任务是通过调用 Task.Run 方法创建的,则可以隐式阻止子任务附加到其中。...view=netcore-3.1 任务返回结果以及异步获取返回结果获取任务返回结果,要使用泛型类或方法创建任务,例如 Task、Task.Factory.StartNew<TResult...,不会直接抛出来阻止主线程执行,当获取任务处理结果或者等待任务完成时,异常会重新抛出。

82430

c#异步编程-Task(二)

在多重程序系统,大部分时间用来做计算、逻辑判断等CPU动作的程序。...(Task.Run调用的代码里) 为了该模型获益,真正的并发代码要避免访问共享状态或UI控件。...c#如何设计异步函数 以同步的方式编写方法 使用异步调用来代替同步调用,并且进行await 除了顶层方法外(UI控件的Event handler),把你方法的返回类型升级为(返回void的类型升级为)...因此,下例,异常会被发布到同步上下文(如果出现的话),不会发布给调用者。...快速返回调用者(只有很小的初始化同步阶段) 如果是I/O绑定,那么无需绑定线程 8.Task组合器 异步函数有一个让其保持一致的协议(可以一致的返回Task),这能让其保证良好的结果:可以使用以及编写Task

2.5K30

Asp.Net Core 轻松学-多线程之Task快速上手

前言     Task是 .NET Framework 4 开始引入的一项基于队列的异步任务(TAP)模式, .NET Framework 4.5 开始,任何使用 async/await 进行修饰的方法...,都会被认为是一个异步方法;实际上,这些异步方法都是基于队列的线程任务,你开始使用 Task 去运行一段代码的时候,实际上就相当于开启了一个线程,默认情况下,这个线程数由线程池 ThreadPool...然后立即迭代此 tasks 获取异步任务的执行结果,使用 TaskFactory 工厂类,可以创建一组人物,然后依次执行它们 2.3 执行上面的代码,输出结果如下 ?...处理 Task 的异常 异步任务中发生异常会导致任务抛出 TaskCancelException 的异常,仅表示任务退出,程序应当捕获该异常;然后,立即调用 Task 进行状态判断,获取内部异常 3.1...,无异常,无中途退出指令的情况下才会表示已完成, task.IsCompleted 则仅仅表示“任务完成” 3.2 执行程序,输出结果 ?

1.5K20

C#:异步编程的 async 和 await

同步和异步概念 异步是相对于同步来说的,同步是指多个方法顺序执行,后一个会等待前一个执行完成后,才开始执行;异步是指调用一个方法 A ,调用后会立即返回(不用等方法 A 执行完成),接着调用后面的方法...当把上面代码的 WaitAll 换成 WaitAny ,可以看出当 task1 执行完成后等待就结束了,调用结果如下: ?...才会被解释成关键字,不会当成是一个函数,所以说当方法中有使用 await 关键字调用异步方法,所在的方法必须使用 async; async不是函数声明的一部分,仅仅是一个标识符,调用者的角度来看,...上面的代码在 Task.Delay(3000); 前面添加了 await 关键字,会发现最后的执行结果为: ? 说明添加 await 关键字之后会进行等待,就让会等待,就变成和同步一样了吗?...Task 当异步方法需要返回一个值,给后面的步骤使用的的时候,就使用 Task,在调用的时候使用 Result 属性进行值的获取

2.4K20

【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理

以下是每个操作的说明和示例代码: 启动线程: 使用Thread类的Start()方法来启动一个新线程。在调用Start()方法后,线程会指定的入口点(方法)开始执行。...以下是Task类的主要特点和使用方法: 创建任务:可以使用Task.Run()方法或者new Task()构造函数来创建任务。...执行异步操作:将需要异步执行的代码块放入任务,任务会自动在新线程或线程池中执行。 等待任务完成:使用await关键字等待任务完成,可以在异步方法等待任务完成,获取返回结果。...它们使得在异步操作处理任务的启动、等待结果获取变得更加简洁和易读。...多任务协作: 在复杂的应用,异步操作可以帮助不同的任务协同工作,例如在一个任务等待另一个任务完成之前执行其他任务。 适用场景包括但不限于: 网络请求:例如,Web服务获取数据,下载文件等。

2.6K44

Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端

多线程的操作在程序也是比较常见的,比如开启一个线程执行一些比较耗时的操作(IO操作),主线程继续执行当前操作,不会造成主线程阻塞。...,至于CPU什么时候调用是需要看情况而定 thread.Start(); Console.WriteLine("程序已经执行完成"); } static void NoParameterMethod...Console.WriteLine(Thread.CurrentThread.ManagedThreadId)), "参数"); ThreadPool是Thread的一个升级版,ThreadPool是线程池中获取线程...,如果线程池中又空闲的元素,则直接调用,如果没有才会创建,Thread则是会一直创建新的线程,要知道开启一个线程就算什么事都不做也会消耗大约1m的内存,是非常浪费性能的,接下来我们写一个例子来看一下二者的区别...5、Async、Await async和await关键字用来实现异步编程,async用来修饰方法,await用来调用方法,await关键字必须出现在有async的方法,await调用方法可以不用async

1.6K21

C#异步使用要点(翻译)

void,所以在调用方法时无法捕捉异常,使得进程崩溃 throw new Exception("异常了"); await Task.Run(() => { }); } 应该将异步函数返回...void 2.对于预计算或者简单计算的函数建议使用Task.FromResult代替Task.Run 对于一些预先知道的结果或者只是一个简单的计算函数,使用Task,FromResult要比Task.Run...程序(例如WinForm)调用Result或wait()并不会死锁(虽然并不建议这么干) 对于预计算或普通计算的函数不应该这么写 public async Task RunAsync()...CancellationToken,所以如果想取消所有调用的异步函数,那么应该将CancllationToken传递给此调用的所有函数 下面例子在调用ReadAsync时并没有传递CancellationToken...,ConcurrentDictionary是一个很好的集合,GetOrAdd也是一个很方便的方法,它用于尝试获取已经存在的项,如果没有则添加项.因为回调是同步的,所以很容易编写Task.Result的代码

3.3K50

使用异步操作时的注意要点(翻译)

void,所以在调用方法时无法捕捉异常,使得进程崩溃 throw new Exception("异常了"); await Task.Run(() => { }); } ☑️应该将异步函数返回...void 2.对于预计算或者简单计算的函数建议使用Task.FromResult代替Task.Run 对于一些预先知道的结果或者只是一个简单的计算函数,使用Task,FromResult要比Task.Run...程序(例如WinForm)调用Result或wait()并不会死锁(虽然并不建议这么干) ❌对于预计算或普通计算的函数不应该这么写 public async Task RunAsync()...CancellationToken,所以如果想取消所有调用的异步函数,那么应该将CancllationToken传递给此调用的所有函数 ❌下面例子在调用ReadAsync时并没有传递CancellationToken...,ConcurrentDictionary是一个很好的集合,GetOrAdd也是一个很方便的方法,它用于尝试获取已经存在的项,如果没有则添加项.因为回调是同步的,所以很容易编写Task.Result的代码

4.6K20

ASP.NET Core 性能最佳做法(上)

3避免阻塞调用 ASP.NET Core 应用应设计为可同时处理许多请求。异步 API 允许较小线程池处理数千个并发请求,无需等待阻塞调用。...线程可以处理另一个请求,不是等待长时间运行的同步任务完成。 ASP.NET Core 应用的一个常见性能问题是阻塞可以异步进行的调用。许多同步阻塞调用都会导致线程池饥饿和响应时间降低。...调用 Task.Run 并立即等待。ASP.NET Core 已经在普通线程池线程上运行应用代码,因此调用 Task.Run 只会导致不必要的额外线程池计划。...建议: 在普通 HTTP 请求处理过程,请勿等待长时间运行的任务完成。 请考虑使用后台服务处理长时间运行的请求,或使用 Azure 函数进行进程外处理。...因此,不应使用异常来控制正常程序流。 建议: 请勿将引发或捕获异常用作正常程序流的一种方法(尤其是在热代码路径)。 请在应用包含逻辑,以检测和处理会导致异常的状况。

1.5K20

关于同步方法里面调用异步方法的探究

但是看了dudu的文章:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相 了解了,这样写是有问题的。但是为什么会有问题呢?...首先我们来看一下,在 void里调用 async 方法,并且要等待async的结果出来之后,才能进行后续的操作。...现在我们定义一个Produce2() 这是一个正常的方法,异步函数调用异步函数。...仔细观察这个图,我们发现第一秒执行了一个Task,第二秒执行了三个Task,第三秒开始,就稳定执行了4-5次Task,这里的时间统计不是很精确,但是可以肯定某个时间开始,程序达到了预期效果,TreadPool...经过上面的分析我们知道,在线程饥饿的情况下,使用同步方法调用异步方法并且wait结果,是会出问题的,那么我们应该怎么办呢? 首先当然是应该避免这种有风险的做法。 其次,还有一种方法

2.5K30

线程详解——c#

在应用程序,写日志是常见的功能,简单分析一下该功能的需求: 在后台异步执行,和其它线程互不影响。...根据上文线程池的两个最优使用条件,由写日志线程会长时间处于阻塞(或运行等待)状态,所以它不适合使用线程池。即不能使用Task.Run最好使用new Thread。...当有新的写日志任务时,将该任务加入到队列,并发出信号。 用一个方法来处理队列的任务,当接收新任务信号时,就依次调用队列的任务。 开发一个功能前需要有个简单的思路,保证心里面有底。...public static void Write(string content) { // WriteLog 方法只是向队列添加任务,执行时间极短,所以使用Task.Run。...Task.Run(() => GetInstance().WriteLog(content)); } } 类写好了,用上文“并发和异步的区别”的代码测试一下这个Logger类,在我的电脑上运行的一次结果

38731

C Sharp(十五)

关于线程: 默认情况下,一个进程只包含一个线程,程序的开始一直执行到结束 线程可以派生其他线程 如果一个进程包含多个线程,他们将共享进程资源 系统为处理器执行所规划的基本单元是线程不是进程 在 C...这个特性是 .Net 框架的一部分,但是没有嵌入 C# 。 async/await 如果程序调用某个方法等待其执行所有处理之后才继续执行,我们称这样的方法为同步方法。...Async 结尾 Lambda 表达式也可以作为异步对象 调用方法读取 Task 的 Result 属性获取 T 类型的值 任何返回 Task 的异步方法必须返回 T 类型的值 需要注意: 不要使用...方法,可能会导致死锁 当第一次遇到 await 表达式所返回的类型就是方法头的返回值类型,与 await 表达式的返回值类型没关系 异步方法的 return 语句并没有真正返回值,只是退出了 在调用方法同步等待任务...我们可能需要在调用方法同步等待某个任务完成,Task 实例提供了 Wait 方法,来等待某个特殊的 Task 完成。

72830

扫码

添加站长 进交流群

领取专属 10元无门槛券

手把手带您无忧上云

扫码加入开发者社群

相关资讯

热门标签

活动推荐

    运营活动

    活动名称
    广告关闭
    领券