C# 如果我的接口必须返回任务,那么实现无操作的最佳方法是什么?
在下面的代码中,由于接口的原因,类C# 如果我的接口必须返回任务,那么实现无操作的最佳方法是什么?,c#,.net,task-parallel-library,async-await,threadpool,C#,.net,Task Parallel Library,Async Await,Threadpool,在下面的代码中,由于接口的原因,类LazyBar必须从其方法返回一个任务(并且为了参数的缘故不能更改)。如果LazyBars实现不寻常,因为它恰好快速同步运行-从方法返回无操作任务的最佳方式是什么 我已经使用了下面的Task.Delay(0),但是我想知道如果函数被多次调用(为了参数起见,比如说每秒数百次),这是否会对性能产生任何副作用: 这是不是有什么大问题 它开始阻塞我的应用程序的线程池了吗 编译器解理器是否足以以不同方式处理延迟(0) 将返回Task.Run(()=>{})有什么不同吗
LazyBar
必须从其方法返回一个任务(并且为了参数的缘故不能更改)。如果LazyBar
s实现不寻常,因为它恰好快速同步运行-从方法返回无操作任务的最佳方式是什么
我已经使用了下面的Task.Delay(0)
,但是我想知道如果函数被多次调用(为了参数起见,比如说每秒数百次),这是否会对性能产生任何副作用:
- 这是不是有什么大问题
- 它开始阻塞我的应用程序的线程池了吗
- 编译器解理器是否足以以不同方式处理
延迟(0)
- 将
返回Task.Run(()=>{})代码>有什么不同吗
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();
}
}
}
使用System.Threading.Tasks;
名称空间MyAsyncTest
{
内部接口IFooFace
{
任务将在大多数实现中异步运行();
}
///
///与大多数情况不同的是,实现不会具有长期运行的性能
///“将在大多数实现中运行异步”中的操作
///
内部类LazyBar:IFooFace
{
#区域IFooFace成员
公共任务将在大多数实现()中异步运行
{
//首先,做一些非常快的事情
var x=1;
//此处无法返回“null”!任务延迟(0)是否有任何性能考虑因素?
//这是一个真正的无操作,或者如果我称之为很多,它会对环境产生不利影响吗
//底层线程池?更好的方法?
返回任务。延迟(0);
//有什么不同吗?
//返回Task.Run(()=>{});
//如果我的任务有结果,我会:
//返回任务.FromResult(12345);
}
#端区
}
内部课程计划
{
私有静态void Main(字符串[]args)
{
Test();
}
专用静态异步无效测试()
{
IFooFace foo=FactoryCreate();
等待foo.willbelong在大多数实现中运行异步();
返回;
}
私有静态IFooFace FactoryCreate()
{
返回新的LazyBar();
}
}
}
今天,我建议使用来完成此任务
.net 4.6之前版本: 使用
Task.FromResult(0)
或Task.FromResult(null)
将比使用无运算表达式创建Task
产生更少的开销。在使用预先确定的结果创建任务时,不涉及调度开销。要添加关于使用任务的内容,请从result
,如果缓存已完成的任务,则可以进一步提高性能,因为已完成任务的所有实例都相同:
public static class TaskExtensions
{
public static readonly Task CompletedTask = Task.FromResult(false);
}
使用TaskExtensions.CompletedTask
可以在整个应用程序域中使用相同的实例
只添加了static属性
Task completedTask = Task.CompletedTask;
Task.Delay(0)
在接受的答案中是一个很好的方法,因为它是已完成的任务的缓存副本
从4.6开始,现在有了Task.CompletedTask
,它的目的更加明确,但不仅仅是Task.Delay(0)
仍然返回单个缓存实例,它返回与Task.CompletedTask
相同的单个缓存实例
两者的缓存性质都不能保证保持不变,但作为依赖于实现的优化,它们仅作为依赖于实现的优化(也就是说,如果实现更改为仍然有效的内容,它们仍然可以正常工作)使用Task.Delay(0)
比公认的答案要好。我更喜欢任务完成任务=Task.completedTask解决方案,但另一种方法是将该方法标记为async并返回void:
public async Task WillBeLongRunningAsyncInTheMajorityOfImplementations()
{
}
您将收到一个警告(CS1998-不带等待表达式的异步函数),但在本上下文中可以安全地忽略此警告。最近遇到此问题,并不断收到有关方法无效的警告/错误
我们的工作是安抚编译器,这就清除了它:
public async Task MyVoidAsyncMethod()
{
await Task.CompletedTask;
}
这是迄今为止所有建议中最好的一个。除非您在方法中实际执行某些操作,否则不需要返回语句。当您必须返回指定类型时:
Task.FromResult<MyClass>(null);
Task.FromResult(空);
如果您使用泛型,所有答案都会给我们提供编译错误。您可以使用返回默认值(T)代码>。下面的示例将进一步解释
public async Task<T> GetItemAsync<T>(string id)
{
try
{
var response = await this._container.ReadItemAsync<T>(id, new PartitionKey(id));
return response.Resource;
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return default(T);
}
}
公共异步任务GetItemAsync(字符串id)
{
尝试
{
var response=等待此消息。_container.ReadItemAsync(id,new PartitionKey(id));
返回响应资源;
}
当(ex.StatusCode==System.Net.HttpStatusCode.NotFound)时捕获(CosmosException ex)
{
返回默认值(T);
}
}
相关问题:就个人而言,我会选择Task.FromResult(null)
。如果您碰巧使用它们,则会提供一个TaskConstants类来提供这些已完成的任务以及其他一些非常有用的任务(0 int,true/false,Default())返回默认值(YourReturnType)
@图例无法直接创建任务我不确定,但是任务。CompletedTask
可能会成功!(但需要.NET4.6)我需要退回还是等待?@Pixar你是什么意思?您可以同时执行这两项操作,但等待操作将同步进行。抱歉,我不得不提到上下文:)在我现在看到的情况下,我们可以使公共任务在大多数实现()中异步运行()
<
public async Task<T> GetItemAsync<T>(string id)
{
try
{
var response = await this._container.ReadItemAsync<T>(id, new PartitionKey(id));
return response.Resource;
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return default(T);
}
}
return await Task.FromResult(new MyClass());