本文翻译自:If my interface must return Task what is the best way to have a no-operation implementation?

In the code below, due to the interface, the class LazyBar must return a task from it's method (and for arguments sake can't be changed). 在下面的代码中,由于接口,类LazyBar必须从它的方法返回一个任务(并且为了参数而不能更改)。 If LazyBar s implementation is unusual in that it happens to run quickly and synchronously - what is the best way to return a No-Operation task from the method? 如果LazyBar的实现很不寻常,因为它恰好快速且同步地运行 - 从该方法返回No-Operation任务的最佳方法是什么?

I have gone with Task.Delay(0) below, however I would like to know if this has any performance side-effects if the function is called a lot (for arguments sake, say hundreds of times a second): 我已经使用了下面的Task.Delay(0) ,但是我想知道如果这个函数被调用了很多,那么它是否有任何性能副作用(为了论证,比如说每秒数百次):

  • Does this syntactic sugar un-wind to something big? 这种语法糖会不会变成大事?
  • Does it start clogging up my application's thread pool? 它是否开始堵塞应用程序的线程池?
  • Is the compiler cleaver enough to deal with Delay(0) differently? 编译器切割器是否足以以不同方式处理Delay(0)
  • Would return Task.Run(() => { }); return Task.Run(() => { }); be any different? 有什么不同吗?

Is there a better way? 有没有更好的办法?

using System.Threading.Tasks;namespace MyAsyncTest
{internal interface IFooFace{Task WillBeLongRunningAsyncInTheMajorityOfImplementations();}/// <summary>/// An implementation, that unlike most cases, will not have a long-running/// operation in 'WillBeLongRunningAsyncInTheMajorityOfImplementations'/// </summary>internal class LazyBar : IFooFace{#region IFooFace Memberspublic Task WillBeLongRunningAsyncInTheMajorityOfImplementations(){// First, do something really quickvar x = 1;// Can't return 'null' here! Does 'Task.Delay(0)' have any performance considerations?// Is it a real no-op, or if I call this a lot, will it adversely affect the// underlying thread-pool? Better way?return Task.Delay(0);// Any different?// return Task.Run(() => { });// If my task returned something, I would do:// return Task.FromResult<int>(12345);}#endregion}internal class Program{private static void Main(string[] args){Test();}private static async void Test(){IFooFace foo = FactoryCreate();await foo.WillBeLongRunningAsyncInTheMajorityOfImplementations();return;}private static IFooFace FactoryCreate(){return new LazyBar();}}
}

#1楼

参考:https://stackoom.com/question/t4yf/如果我的接口必须返回Task-那么实现无操作的最佳方法是什么


#2楼

Using Task.FromResult(0) or Task.FromResult<object>(null) will incur less overhead than creating a Task with a no-op expression. 使用Task.FromResult(0)Task.FromResult<object>(null)将比使用no-op表达式创建Task产生更少的开销。 When creating a Task with a result pre-determined, there is no scheduling overhead involved. 在创建具有预先确定结果的Task时,不会涉及调度开销。


Today, I would recommend using Task.CompletedTask to accomplish this. 今天,我建议使用Task.CompletedTask来实现这一目标。


#3楼

To add to Reed Copsey's answer about using Task.FromResult , you can improve performance even more if you cache the already completed task since all instances of completed tasks are the same: 要添加Reed Copsey关于使用Task.FromResult 的答案 ,如果缓存已完成的任务,则可以进一步提高性能,因为已完成任务的所有实例都相同:

public static class TaskExtensions
{public static readonly Task CompletedTask = Task.FromResult(false);
}

With TaskExtensions.CompletedTask you can use the same instance throughout the entire app domain. 使用TaskExtensions.CompletedTask您可以在整个应用程序域中使用相同的实例。


The latest version of the .Net Framework (v4.6) adds just that with the Task.CompletedTask static property 最新版本的.Net Framework(v4.6)只增加了Task.CompletedTask静态属性

Task completedTask = Task.CompletedTask;

#4楼

Task.Delay(0) as in the accepted answer was a good approach, as it is a cached copy of a completed Task . 在接受的答案中, Task.Delay(0)是一个很好的方法,因为它是已完成的Task的缓存副本。

As of 4.6 there's now Task.CompletedTask which is more explicit in its purpose, but not only does Task.Delay(0) still return a single cached instance, it returns the same single cached instance as does Task.CompletedTask . 从4.6开始,现在的Task.CompletedTask在其目的上更加明确,但不仅Task.Delay(0)仍返回单个缓存实例,它返回Task.CompletedTask 相同的单个缓存实例。

The cached nature of neither is guaranteed to remain constant, but as implementation-dependent optimisations that are only implementation-dependent as optimisations (that is, they'd still work correctly if the implementation changed to something that was still valid) the use of Task.Delay(0) was better than the accepted answer. 两者的缓存性质都不能保证保持不变,而是作为依赖于实现的优化,它们只是依赖于实现的优化(也就是说,如果实现改变为仍然有效的东西,它们仍能正常工作)使用Task.Delay(0)比接受的答案好。


#5楼

I prefer the Task completedTask = Task.CompletedTask; 我更喜欢Task completedTask = Task.CompletedTask; solution of .Net 4.6, but another approach is to mark the method async and return void: .Net 4.6的解决方案,但另一种方法是将方法标记为异步并返回void:

    public async Task WillBeLongRunningAsyncInTheMajorityOfImplementations(){}

You'll get a warning (CS1998 - Async function without await expression), but this is safe to ignore in this context. 您将收到警告(CS1998 - 没有等待表达式的异步函数),但在此上下文中可以安全地忽略。


#6楼

Recently encountered this and kept getting warnings/errors about the method being void. 最近遇到这个并且不断收到关于该方法无效的警告/错误。

We're in the business of placating the compiler and this clears it up: 我们正在安抚编译器并清除它:

    public async Task MyVoidAsyncMethod(){await Task.CompletedTask;}

This brings together the best of all the advice here so far. 到目前为止,这里汇集了所有建议中的最佳建议。 No return statement is necessary unless you're actually doing something in the method. 除非您实际在该方法中执行某些操作,否则不需要返回语句。

如果我的接口必须返回Task,那么实现无操作的最佳方法是什么?相关推荐

  1. 异步接口同步返回_Dubbo客户端异步接口的实现背景和实践

    铺垫 先简单介绍下一次完整的Dubbo调用所经历的线程阶段.几个信息这里罗列下 Biz~代表业务线程,即便是业务逻辑处理所处的线程,Biz~线程池可能是业务自己创建维护,大多数的可能是系统框架自身管理 ...

  2. 【转】2.3async中必须始终返回Task(@Ron.liang)

    Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章 目录 前言 1. 异常的发生来得太突然 2. 问题所在 3. 问题的解决方案 前言 事情的起因是由于一段简单的数据库连接代码引 ...

  3. 对接京东获取任务工单接口jingdong.homefw.task.search,附接口字段详细说明,数据库设计,Java实现

    目录 接口详细说明 jingdong.homefw.task.search(获取任务工单) 任务工单字段详细说明 数据库设计 任务工单表结构 日志表结构 接口Java实现 接口详细说明 jingdon ...

  4. ajax调取json接口,通过 Ajax 调取后台接口将返回的 json 数据绑定在页面上

    第一步: 编写基础的 html 框架内容,并引入 jquery: 测试Ajax 第二步: 在 " " 中间插入要点击的按钮和用来显示数据的 标签,并编写对应的 function: ...

  5. (转) 服务接口统一返回的格式

    1.14.1 统一返回的格式 很明显地,默认情况下,我们选择了 JSON 作为统一的格式返回接口结果.这里简单说明一下选取JSON统一返回的原因: JSON当前很流行,且普通接口都采用此格式返回 JS ...

  6. 异步/等待-什么时候返回Task vs void?

    本文翻译自:async/await - when to return a Task vs void? Under what scenarios would one want to use 在什么情况下 ...

  7. JAVA接口返回面积_java – 将接口的返回值限制为实现类的范围

    我正在编写一个小型库,我有一些接口提供了一个返回值应该在指定范围内的方法.我如何明确禁止实现此方法的库的用户返回不在此范围内的值? 像这样的东西: //Library interface Favori ...

  8. SpringBoot+El-upload实现上传文件到通用上传接口并返回文件全路径(若依前后端分离版源码分析)

    场景 SpringBoot+ElementUI实现通用文件下载请求(全流程图文详细教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  9. php接口返回错误码,laravel 错误处理,接口错误返回json代码

    Laravel 默认已经为我们配置好了错误和异常处理,我们在 App\Exceptions\Handler 类中触发异常并将响应返回给用户. 所有异常都由类App\Exceptions\Handler ...

最新文章

  1. elasticsearch-5.0.0初见
  2. 用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
  3. js流程图:aworkflow.js
  4. Linux 网卡信息查看
  5. C#自定义序列化反序列化与 ISerializable 接口
  6. github出现Your account has been flagged.导致账号无法公开的解决办法
  7. math属于python标准库吗_python标准库《math》
  8. VBA精彩代码分享-4
  9. phpcms如何做企业站-- 替换首页最初操作
  10. JavaScript学习总结(二十)——Javascript非构造函数的继承
  11. 制作JD的手动和自动轮播图片板块
  12. winform界面嵌入dwg图纸_完美解决窗体中预览DWG图形(C#版)
  13. de4dot不能反编译的混淆工具 ILProtector
  14. ADXL361(微功耗三轴加速度计)使用笔记
  15. win7 c盘空间不足怎么扩大
  16. 新款 2018款macbook Pro 装双系统教程
  17. The Dominator of Strings
  18. VS2017下解决:error LNK2019: 无法解析的外部符号 __iob_func
  19. Localize Folders and Reports
  20. access 有效性规则和有效性文本

热门文章

  1. Andorid的Linux基础教学之四 进程的生死存亡
  2. 算法---------数组-----------两数相加
  3. Android-无障碍服务(AccessibilityService)
  4. Android的ImageView背后的绘制原理
  5. Android EventBus 的使用
  6. 第十五周程序阅读-范型程序设计(6)
  7. Android Studio 项目打包成apk时 Signature Version 的选择
  8. SpringMVC基础——一个简单的例子
  9. 河北计算机应用技术,[河北科技大学]计算机应用技术
  10. python复制文件夹不阻塞_Python学习第54天(阻塞(blocking) IO和非阻塞(non-blocking)IO)...