C# 在异步方法中处理空任务的最佳方法?

C# 在异步方法中处理空任务的最佳方法?,c#,.net,task-parallel-library,async-await,C#,.net,Task Parallel Library,Async Await,在async方法中处理null任务的最佳方法是什么 公共类MyClass { 私有只读任务; 公共MyClass(任务任务){this.Task=Task;} 公共异步任务执行() { 如果(任务==null) { 等待任务。Yield();/*这是最好的方法吗*/ 返回; } 等待任务; } } 您不需要处理null任务。只需检查它: public async Task Execute() { if (task != null) { await task; }

async
方法中处理
null
任务的最佳方法是什么

公共类MyClass
{
私有只读任务;
公共MyClass(任务任务){this.Task=Task;}
公共异步任务执行()
{
如果(任务==null)
{
等待任务。Yield();/*这是最好的方法吗*/
返回;
}
等待任务;
}
}

您不需要处理
null
任务。只需检查它:

public async Task Execute()
{
   if (task != null)
   {
       await task;
   }
}
或者更好的方法是,简单地返回任务,因为在
wait
之后没有添加任何内容:

public Task Execute()
{
   return task;
}
如果要返回已完成的任务而不是
null
,可以使用
task.FromResult

public Task Execute()
{
   return task ?? Task.FromResult(false);
}

如果任务从不为空,则大多数异步代码更干净。使用
task.FromResult(0)
或类似的构造,而不是空任务

public class MyClass
{
  private readonly Task task;
  public MyClass(Task task) { this.task = task ?? Task.FromResult(0); }

  public async Task ExecuteAsync()
  {
    await task;
  }
}
或者,如果您的
ExecuteAsync
真的就是这么做的:

public Task ExecuteAsync()
{
  return task;
}
请注意,调用构造函数时任务已经在运行,这使得方法名
ExecuteAsync
用词不当。如果希望在调用
ExecuteAsync
时启动任务,则真正需要存储的是
Func

公共类MyClass
{
私有只读函数Func;
公共MyClass(Func Func){this.Func=Func???()=>Task.FromResult(0);}
公共异步任务ExecuteAsync()
{
等待函数();
}
}
在异步方法中处理空任务的最佳方法是什么

最佳实践通常包括不允许空参数(除非业务规则需要)


你想做什么?我想说
publicmyclass(Task任务){if(Task==null)抛出新的ArgumentNullException(“Task”);…}
就是不要接受null任务。顺便说一句,你想做什么?包装一个任务并添加一个execute方法是非常可疑的,可能是一种代码味道——当没有理由启动或执行任务时,试图“控制”任务。任务本身是一个在其委托启动和执行时进行抽象的类,您不需要在其上添加另一个类来执行同样的操作。我试图了解在异步方法中处理可能为空的任务的最佳实践。在本次讨论中,我们假设我继承了一个可能允许空任务的方法,并且在构造函数中添加空检查不是一个选项。“Task.FromResult(false)”在具有不能严格抽象的可重写方法时非常有效。谢谢你的回答。既然Elvis操作符如此常见(
)——我有一个扩展方法,它使用这种方法来确保那些等待调用始终有效:
公共静态任务NullSafe(此任务)=>任务??Task.FromResult(默认值(T))--因此您可以编写类似于
var x=await(someObject?.DoTheThing()).NullSafe()的代码(请记住,由于Elvis运算符的工作方式,括号在该语句中很重要。)“Task.CompletedTask”也是一个选项
public class MyClass
{
  private readonly Func<Task> func;
  public MyClass(Func<Task> func) { this.func = func ?? () => Task.FromResult(0); }

  public async Task ExecuteAsync()
  {
    await func();
  }
}
public class MyClass
{
   private readonly Task _task;

   public MyClass(Task task) 
   { 
     if (task == null)
     {
       throw new ArgumentNullException("task");
     }

     this._task = task; 
   }

   public async Task Execute()
   {
      await this._task;
   }
}