首页
学习
活动
专区
圈层
工具
发布

C# await 高级用法

如果一个类需要可以被等待,那么这个类必须满足以下条件 类里有一个 GetAwaiter 函数 GetAwaiter 有返回值,返回值需要继承 INotifyCompletion 并且有 bool...Awaiter - walterlv 但是上面的代码使用的是一个字符串,什么时候可以修改继承字符串?...先让我来说下 await 原理,因为知道了原理,上面的代码实现很简单。看完了本文,你就会知道如何让几乎所有类型包括 int 、string 、自定义的类都支持 await 。...如果感兴趣 await 不一定会进入一个新的线程请看 There Is No Thread 使用 因为 await 需要找到一个 GetAwaiter 函数,这个函数即使是扩展方法也可以,所以其实上面的代码是这样写的...但是依旧遇到一些小伙伴一直以为全部的异步方法都需要await,看到我写了没有直接await的代码觉得很诡异,所以我在这里做个实验给大家看。

1K10

C# await 高级用法

如果一个类需要可以被等待,那么这个类必须满足以下条件 类里有一个 GetAwaiter 函数 GetAwaiter 有返回值,返回值需要继承 INotifyCompletion 并且有 bool...Awaiter - walterlv 但是上面的代码使用的是一个字符串,什么时候可以修改继承字符串?...先让我来说下 await 原理,因为知道了原理,上面的代码实现很简单。看完了本文,你就会知道如何让几乎所有类型包括 int 、string 、自定义的类都支持 await 。...如果感兴趣 await 不一定会进入一个新的线程请看 There Is No Thread 使用 因为 await 需要找到一个 GetAwaiter 函数,这个函数即使是扩展方法也可以,所以其实上面的代码是这样写的...但是依旧遇到一些小伙伴一直以为全部的异步方法都需要await,看到我写了没有直接await的代码觉得很诡异,所以我在这里做个实验给大家看。

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

    如何实现一个可以用 await 异步等待的 Awaiter

    标注“此处为试验代码”的代码块表明此处代码并不完善,仅用于本文分析使用,不建议放到自己的项目中使用。 没有注释标注的代码块是用于研究的代码片段,不需要使用。 可点击下面的导航跳转到你希望的地方。...async/await 是给编译器用的,只要我们的类包含一个 GetAwaiter 方法,并返回合适的对象,我们就能让这个类的实例被 await 使用了。...现在提示变成了: await 要求类型 Test 包含适当的 GetAwaiter 方法。...此类 A 有一个可被访问到的 GetAwaiter 方法(扩展方法也行,这算是黑科技吗?)...定义抽象的 Awaiter/Awaitable 这里我们发现一个神奇的现象——明明那些属性和方法都是不可缺少的,却并没有接口来约束它们,而是靠着编译器来约束。

    2.7K20

    c#异步编程-Task(二)

    二、详细内容 1.同步异步 同步操作会在返回调用者之前完成它的工作 异步操作会在返回调用者之后去做它的工作 异步的方法更为少见,会启用并发,因为他的工作会与调用者并行执行 目前见到的大部分的异步方法都是通用目的的...在几口内使用async是没有意义的 使用async来重载飞async的方法却是合法的(只要方法签名一致) 使用了async修饰符的方法就是“异步函数”。...示例代码: public async Task Go(){ //这里不要return,但必须有await的方法在Go的函数体内 } 编译器会对返回Task的异步函数进行扩展,使其成为发送信号或发生故障时使用...我们创建一个“futures”(Task)的缓存,而不是字符串的缓存。...这里ContinueWith要比GetAwaiter().OnCompleted更方便,因为我们不访问Task的result,并且此刻不想弹回到UI线程。

    2.9K30

    理解Task和和async await

    上面埋下的彩蛋在这里揭晓了,在讲Task的延续的时候我们讲到.NET Framework4.5的一种通过GetAwaiter延续方法,事实上,async await就是上面的一种语法糖,编译的时候大致会编译成那样...,所以我们一般不手动写GetAwaiter的延续方法,而是通过async await,大大简化了编程方式,说它是语法糖,那么有啥证据呢?...的对象,它必须包含以下条件: 有一个GetAwaiter方法,为实例方法或者扩展方法 GetAwaiter方法的返回值类,必须包含以下条件 直接或者间接实现INotifyCompletion...await的类,关于如何自定义的细节,可以参考林德熙大佬的这篇文章:C# await 高级用法 async await的正确用途 事实上,我们在线程池上还埋下一个彩蛋,线程池上有工作线程适合CPU密集型操作...(这能避免之前回调的时候阻塞I/O完成端口线程的操作),但是大大的简化了异步I/O编程,而async await并非不适合CPU密集型,只是I/O操作一般比较耗时,如果用线程池的工作线程,就会有可能创建更多线程来应付更多的请求

    2.6K30

    .NET 异步详解

    最典型的比如通过前后线程 ID 来推断其工作方式、在 async 方法中用 Thread.Sleep 来解释 Task 机制而导出多线程模型的结论、在 Task.Run 中包含 IO bound 任务来推出这是开了一个多线程在执行任务的结论等等...要了解 .NET 中的 async/await 机制,首先需要有操作系统原理的基础,否则的话是很难理解清楚的,如果没有这些基础而试图向他人解释,大多也只是基于现象得到的错误猜想。...初看异步 说到异步大家应该都很熟悉了,2012 年 C# 5 引入了新的异步机制:Task,并且还有两个新的关键字 await 和 async,这已经不是什么新鲜事了,而且如今这个异步机制已经被各大语言借鉴...的 Promise 的工作方式了。...在 C# 中只要你的类中包含 GetAwaiter() 方法和 bool IsCompleted 属性,并且 GetAwaiter() 返回的东西包含一个 GetResult() 方法、一个 bool

    99654

    面试必备:C#多线程技术

    Task(和其相关类型)都被增强了,以包含更过支持TAP和异步编程的原语(如,GetAwaiter()、Task.WhenAll 等)。...async/await async/await关键字,主要用于我们使用顺序结构(而不是使用回调)来实现异步编程。极大增强异步编程的可读性。...async会创建新线程还是await会创建新线程 都不会,async/await可以理解为一种异步的结构同步化语法糖,具体的新线程还是通过Task.Run()等代码创建。...在await的代码中不返回Task,返回void不行吗 不行,await后面跟着的必须是一个等待表达式,如Task,Task。返回void,或其他参数会报错。"...CS4008:无法等待void"或“CS1061:bool未包含GetAwaiter的定义,并且找不到可接受第一个bool类型参数的可访问扩展方法GetAwaiter(是否缺少 using 指令或程序集引用

    94440

    Async,Await和ConfigureAwait的关系

    但是,使用它们,方法的返回类型应为Task类型。(我们将在稍后讨论例外情况)为了使用await关键字,您必须在方法定义中使用async。...使用async/ await,其他人可以在你点完菜之后下他们的订单,并且可以同时处理多个订单。 它不能做什么? 这里需要注意的一件事是async/await并不是并行/多核编程。...如果不这样做,就会导致另一个死锁。这里的问题是,每个async/ await对于调用它的当前方法都是本地的。因此,调用链的每个异async/await都可能最终在不同的线程上恢复。...如果你把一个任务放在那里,程序将无法编译,并且返回某些东西的事件会感觉很奇怪。如果该按钮调用异步async,则必须执行async void才能使其正常工作。...,是否哪里没有设置ConfigureAwait(false) 会导致的死锁问题,因为在.netcore中的async/await 可能在任何线程上执行,并且可能并行运行!

    1K10

    dotnet 使用 TaskTupleAwaiter 同时等待多个任务简化代码写法

    ); 但千万不要先等待第一个任务执行完成,再等待第二个任务执行完成哦,如果是如以下代码的写法,自然会没有充分利用资源,第二个任务还在等待中 var foo1 = await GetFoo1Async()...; var foo2 = await GetFoo2Async(); 在异步任务超过 3 个之后,代码逻辑的长度自然就很长了。...,里面就对 ValueTuple 扩展了 GetAwaiter 方法,根据 C# await 高级用法 博客可以了解到,对于 await 等待来说,只需要等待的类型存在 GetAwaiter 方法且此...GetAwaiter 方法返回一个实现了等待相关方法的类型的对象即可 例如对于由三个 Task 任务组成的 ValueTuple 加上可等待的功能的扩展方法可以是如下代码 public static...扩展方法,给 (Task, Task, Task) 扩展了可等待的方法,如此即可使用 await 进行等待 通过 TupleTaskAwaiter 实现具体的等待逻辑,核心实现依然是

    77820

    关于CS1061报错(XX不包含XXX的定义,并且找不到类型为XX的第一个参.....)的一种可能的解决的办法

    在我编程中,我遇到了一个这样的报错, 可是我引用的product类中又确实定义了这么一个方法, protected void BindPageData(int categoryID) {...dv.Sort = "SaleNumber DESC"; gvProduct.DataSource = dv; gvProduct.DataBind(); } 类中的方法代码...Pr_GetProductByFenlei " + categoryID + ""; return db.getDataTableBySQL(sql); } 在网上搜索了关于cs1061报错的解决办法...,都没有解决这个问题,后面在观察中,我除了定义了一个product.cs的类外,还定义了一个同名为Product.aspx的web窗体, 是不是因为是同名,所以在编译过程中出现了冲突呢?...我就把类的名字改了以下,ctrl+f5   完美运行。所以大家在遇到这种报错的是否,考虑是否是否是同名的问题。另外,不管是不是正确的决绝办法,都应该多尝试。

    2.9K60

    C# 中的细节

    不是只有 Task 和 ValueTask 才能 await# 在 C# 中编写异步代码的时候,我们经常会选择将异步代码包含在一个 Task 或者 ValueTask 中,这样调用者就能用 await...Task 和 ValueTask 背后明明是由线程池参与调度的,可是为什么 C# 的 async/await 却被说成是 coroutine 呢?...因为你所 await 的东西不一定是 Task/ValueTask,在 C# 中只要你的类中包含 GetAwaiter() 方法和 bool IsCompleted 属性,并且 GetAwaiter()...返回的东西包含一个 GetResult() 方法、一个 `bool IsCompleted属性和实现了INotifyCompletion,那么这个类的对象就是可以await` 的 。...UWP 开发中所用的 IAsyncAction/IAsyncOperation 则是来自底层的封装,和 Task 没有任何关系但是是可以 await 的,并且如果用 C++/WinRT 开发 UWP

    3.1K00

    多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder

    引言         之前在上一篇文章中多线程合集(二)---异步的那些事,async和await原理抛析,我们从源码去分析了async和await如何运行,以及将编译后的IL代码写成了c#代码,以及实现自定义的...,导致我推不过去,上一层也找不到结果,此处我没有具体分析,但是我的猜测是这样,看官们可以自己尝试一下,将MyTask的GetAwaiter注释,使用默认的TaskAwaiter,然后调用Test方法,如果是...的type,即要么在MyTask类上面使用此特性,也可以直接在Test方法上面添加此特性都可以实现自定义Builder,当然了此处有个扩展就是你可以参考上一章节的自定义状态机,调度器,awaiter,自己手动实现编译器编译之后的代码...,但是结合前几篇,也可以更好的理解async和await了。...,因为大家能更好的理解async和await,能够将这些自定义的东西玩出花来,哈哈,关于async和await以及线程方面,感兴趣的可以看看我之前的文章。

    42710

    揭秘C#异步编程核心机制:从状态机到线程池的全面拆解

    1.2 C#中的async和await C#通过async和await关键字简化了异步编程的编写: **async**:标记一个方法为异步方法,表示它可能包含异步操作。...该接口定义了两个方法: **MoveNext**:驱动状态机执行,是状态机的核心逻辑。 **SetStateMachine**:用于跨AppDomain场景,通常不直接使用。...4.2 C#中async/await的工作原理 在C#中,当你使用async和await时,编译器会将方法转化为一个状态机。这个状态机负责: 在await处暂停方法的执行。...().ConfigureAwait(false);     return "Data"; // 不恢复到原始上下文 } 即使有人对async/await的工作流程有了相当不错的理解,但对于嵌套异步调用链的行为仍有很多困惑...自定义Awaiter和扩展性 6.1 Awaiter模式 C#支持await任何实现了awaiter模式的类型,要求: 提供GetAwaiter方法,返回一个awaiter对象。

    1K10

    .NET系列走进Task:Task的回调执行与await

    前言 上一篇我们讲了对 Task 的基本定义:Task 代表一个任务,其具体类型可能是多种多样的,且有时候对我们来说完全是个黑盒。...await Anything C# 编译器并没有限制 await 关键词只能用在 Task 上。...AsyncTaskMethodBuilder 是状态机的一个重要组成部分,负责 状态机与 awaiter 的衔接工作,更详细的功能我们下篇博客再叙述,这边只简单提一下。...动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。...3、状态机:由编译器生成,每个 async 方法 有且仅有一个,await 后面的代码会被编译到 状态机 的 MoveNext 方法中,注册为 Task 的回调。

    3.1K30

    .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?

    .NET 中的 async / await 写异步代码用起来真的很爽,就像写同步一样。我们可以在各种各样的异步代码中看到 Task 返回值,这样大家便可以使用 await 等待这个方法。...不过,有时需要写一些特别的异步方法,这时需要自己来实现一个可以异步等待的对象。 本文将讲述如何实现一个可等待对象,一个自定义的 Awaiter。...定义一组抽象的 Awaiter 的实现接口,你下次写自己的 await 可等待对象时将更加方便 .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?...编写基本的 Awaiter 框架代码 先写一个空的类型,然后为它编写一个空的 GetAwaiter 方法,返回新的 WalterlvAwaiter 类型。...另外两个方法不是接口带来的,但是也是实现一个自定义的 Awaiter 必要的方法。 在你编写完以上两段代码之后,你的 await 就可以编译通过了。

    73010

    你所不知道的C#中的细节

    不是只有 Task 和 ValueTask 才能 await 在 C# 中编写异步代码的时候,我们经常会选择将异步代码包含在一个 Task 或者 ValueTask 中,这样调用者就能用 await 的方式实现异步调用...Task 和 ValueTask 背后明明是由线程池参与调度的,可是为什么 C# 的 async/await 却被说成是 coroutine 呢?...因为你所 await 的东西不一定是 Task/ValueTask,在 C# 中只要你的类中包含 GetAwaiter() 方法和 bool IsCompleted 属性,并且 GetAwaiter()...返回的东西包含一个 GetResult() 方法、一个 bool IsCompleted 属性和实现了 INotifyCompletion,那么这个类的对象就是可以 await 的 。...UWP 开发中所用的 IAsyncAction/IAsyncOperation 则是来自底层的封装,和 Task 没有任何关系但是是可以 await 的,并且如果用 C++/WinRT 开发 UWP

    47610
    领券