If my interface must return Task what is the best way to have a no-operation implementation? 
在下面的代码中,由于接口的原因,类LazyBar 必须从它的方法返回一个任务(为了参数,不能更改)。如果LazyBar 的实现是不寻常的,因为它恰好快速同步地运行——从该方法返回无操作任务的最佳方法是什么?
我已经使用下面的Task.Delay(0) ,但是我想知道,如果函数被大量调用,这是否有任何性能副作用(为了参数起见,每秒数百次):
这种句法上的甜言蜜语是否意味着一件大事? 
它是否开始阻塞应用程序的线程池? 
编译器解释器是否足以处理Delay(0) 不同的问题? 
return Task.Run(() => { }); 有什么不同吗? 
 
有更好的方法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
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 Members 
        public  Task WillBeLongRunningAsyncInTheMajorityOfImplementations
( ) 
        { 
            // First, do something really quick 
            var  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
( ) ; 
        } 
    } 
} 
 
		
		
相关问题:stackoverflow.com/questions/4245968/create-a-completed-task 
就我个人而言,我会和Task.FromResult(null)  一起去。 
 
 
	  
使用Task.FromResult(0) 或Task.FromResult(null)  比使用no-op表达式创建Task 的开销要小。当创建一个结果预先确定的Task 时,不涉及调度开销。
今天,我建议您使用task.completedtask来完成此任务。
		
		
如果您碰巧使用github.com/stephencleary/asyncex,它们会提供一个taskconstants类来提供这些已完成的任务以及其他一些非常有用的任务(0 int,true/false,default())  
return  default(YourReturnType);  
@无法直接创建任务的图例 
我不确定,但江户十一〔一〕可能会耍花招!(但需要.NET 4.6) 
@彼得,是的,那现在会更好。 
问题:返回Task 的Task.FromResult 如何满足Task 的返回类型(无类型参数)? 
如果我在async Task 方法中什么都不做(比如说不满足等待的条件),最终会同步运行吗? 
 
 
	  
为了增加Reed Copsey关于使用Task.FromResult 的回答,如果缓存已完成的任务,则可以提高性能,因为已完成任务的所有实例都是相同的:
1 2 3 4
public  static  class  TaskExtensions 
{  
    public  static  readonly  Task CompletedTask =  Task. FromResult ( false ) ;  
} 
 
使用TaskExtensions.CompletedTask ,您可以在整个应用程序域中使用相同的实例。
最新版本的.NET框架(v4.6)只添加了带有Task.CompletedTask 静态属性的内容。
1
Task completedTask =  Task. CompletedTask ; 
 
		
		
我需要退回还是等待? 
@皮克斯,你什么意思?您可以同时执行这两项操作,但等待将同步进行。 
不好意思,我不得不提一下上下文:)我现在看到了,我们可以做public Task WillBeLongRunningAsyncInTheMajorityOfImplementations() 和public async Task WillBeLongRunningAsyncInTheMajorityOfImplementations() 。所以,我们可以选择return CompletedTask; 或await CompletedTask; 。什么是更可取的(也许更有效或更一致)? 
@pixar no async的效率会更高。不管怎样,如果您选择了异步,那么您就不需要一个完成的任务来开始(async Task DoAsync() { } )。 
所以,这应该是乔恩问题的答案吗? 
@皮克斯我不清楚。我的意思是"不异步"会更有效。使方法异步将指示编译器将其转换为状态机。它还将在每次调用时创建一个新任务。返回一个已经完成的任务将更清晰和更有效。 
好吧,现在我明白了。非常感谢你!:) 
出于好奇,缓存已解决的任务将如何影响性能? 
@它减少了分配(以及使用它的GC时间)。每次需要一个已完成的任务时,您只需分配一次新内存和构造一个任务实例,而不必每次都分配一个新内存。 
@i3arnon afaik Task.FromResult 已经缓存了所有内容。 
@Alexzhukovskiy它不能也不能,这基本上是一个内存泄漏,因为它不知道它可能接收多少可能的值。为true 和false 缓存2个任务是可以的,但是为int 缓存40亿任务是很有问题的。 
@i3提示尚未完成,但将实施。 
@亚历克朱可夫斯基1。这是一个不同的API。Task.FromResult 仍不缓存。2。这是一个建议,并不意味着它会被执行。 
@我3警告你没有读到第一条被否决的评论? 
@我有亚历克朱可夫斯基。Task.FromResult 将缓存所有内容的可能性为零。它可能会缓存一些常见值,如true 、false 、0 和其他一些默认值。 
@我明白你的意思了。如果缓存一些默认值就足够了。 
最好调用此taskConstant,因为它将与system.threading.tasks.taskSextures冲突。 
 
 
	  
  
在接受的答案中,Task.Delay(0) 是一种很好的方法,因为它是已完成Task 的缓存副本。
从4.6开始,现在有了Task.CompletedTask ,目的更加明确,但Task.Delay(0) 不仅返回单个缓存实例,而且返回的单个缓存实例与Task.CompletedTask 相同。
两者的缓存性质都不能保证保持不变,但作为仅依赖于实现的依赖于实现的优化(即,如果实现更改为仍然有效的内容,它们仍然可以正常工作),使用Task.Delay(0) 比公认的答案更好。
		
		
我仍然在使用4.5,当我做一些研究时,我很高兴找到了那个任务。delay(0)是一个特殊的情况,返回一个静态完成的任务成员。然后缓存在自己的静态完成任务成员中。P 
我不知道为什么,但是Task.CompletedTask 不能用于PCL项目,即使我将.NET版本设置为4.6(配置文件7),刚刚在VS2017中测试过。 
@Fay我想这肯定不是PCL API表面的一部分,尽管目前唯一能做的事情就是支持PCL也支持4.5,所以我已经不得不用我自己的Task.CompletedTask => Task.Delay(0); 来支持它了,所以我不太清楚。 
 
 
	  
最近遇到此问题,并不断收到有关该方法无效的警告/错误。
我们的任务是安抚编译器,这就清楚了:
1 2 3 4
    public  async  Task MyVoidAsyncMethod( )  
    {  
        await  Task. CompletedTask ;  
    } 
 
这就汇集了迄今为止最好的建议。除非您在方法中实际做了一些事情,否则不需要返回语句。
		
		
那是完全错误的。因为方法定义包含异步,所以您收到一个编译器错误,所以编译器需要等待。"正确"用法为public task myvoidAsyncMethog()return task.completedTask; 
不知道为什么投了反对票,因为这似乎是最清楚的答案。 
因为基思的评论。 
他没有完全错,只是删除了async关键字。我的方法更惯用。他是个极简主义者。如果不是有点粗鲁。 
这没有道理,完全同意基思的观点,我并没有得到所有的赞成票。为什么要添加不必要的代码?public Task MyVoidAsyncMethod() {} 与上述方法完全相同。如果有这样使用它的用例,请添加额外的代码。 
我的用例是'public async task myvoidAsyncMethod()if!调试..dostuff…#endif等待task.completedtask; 
以避免无效警告。除非他们已经更新了编译器来停止这样做。 
 
 
	  
我更喜欢.NET 4.6的Task completedTask = Task.CompletedTask; 解决方案,但另一种方法是将方法标记为Async并返回void:
1 2 3
    public  async  Task WillBeLongRunningAsyncInTheMajorityOfImplementations( )  
    {  
    } 
 
您将收到一个警告(CS1998-Async函数,不带await表达式),但在这个上下文中可以安全地忽略它。