C# C中返回任务的正确方法#

C# C中返回任务的正确方法#,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我有一个场景,在这个场景中,我需要返回一个可以从调用方等待的方法 我这里有我的实现,我只想知道哪一个是正确的 方法1 public class ClassA { public Task MyTask { get; set; } public ClassA() { MyTask = MyAsyncMethod(); } private async void MyAsyncMethod() { await LongProc

我有一个场景,在这个场景中,我需要返回一个可以从调用方等待的方法

我这里有我的实现,我只想知道哪一个是正确的

方法1

public class ClassA
{
    public Task MyTask { get; set; }
    public ClassA()
    {
       MyTask = MyAsyncMethod();
    }

    private async void MyAsyncMethod()
    {
       await LongProcessHere();
    }
}

public class MyCaller()
{
   private async void ExecuteAsync()
   {
      ClassA ca = new ClassA();
      await ca.MyTask;
   }
}
方法2

public class ClassA
{
    public Task MyAsyncMethod()
    {
       return Task.Run(async()=>
       {
          await LongProcessHere();
       });
    }
}

public class MyCaller()
{
   private async void ExecuteAsync()
   {
      ClassA ca = new ClassA();
      await ca.MyAsyncMethod();
   }
}

正确的代码如下所示:

公共类ClassA
{
//始终从异步方法返回任务
公共异步任务MyAsyncMethod()
{
在这里等待漫长的过程();
}
}
公共类MyCaller
{
专用异步任务ExecuteAsync()
{
ClassA ca=新的ClassA();
等待ca.MyAsyncMethod();
}
}
如果您问我是否应该公开属性或方法,那么这完全取决于任务所代表的内容

如果任务是类的每个实例执行一次,那么使用
task
属性是合适的。通常在这种情况下,属性表示实例的某些方面,例如或

如果任务是需要多次执行的,那么使用
任务
-返回方法是合适的

Task
-返回方法比
Task
属性更常见


另外,和。

您不需要使用Task.Run调用异步方法。异步方法也应该有任务返回类型,而不是void。反之亦然

public class ClassA
{
    public async Task MyAsyncMethod()
    {
       return await LongProcessHere();
    }
}

public class MyCaller()
{
   private async Task ExecuteAsync()
   {
      ClassA ca = new ClassA();
      await ca.MyAsyncMethod();
   }
}

两者都不正确,因为两者都使用
async void
。如果您的方法是
async
,那么它应该返回
任务
,以便等待
async void
仅为与事件处理程序向后兼容而存在,不应在此之外使用。(并且在其中非常小心地使用。)构造函数永远不应该开始后台工作,因此1被丢弃。您不应该在任务中包装调用。在不需要时运行,因此2也会被丢弃。@Camiloterevento为什么在构造函数中启动后台工作不好?@TheodorZoulias,因为构造函数只是为了确保传入正确的数据。没有人知道后台工作是否在那里开始,也没有办法优雅地处理这些后台错误tasks@user2964556不,那是不对的。调用异步方法将启动任务。我在方法2中的代码是否不正确?你的也一样。尽管如此,我还是在方法2中返回了一个任务,只是返回了一个Task.run来处理长时间运行的任务。在
MyAsyncMethod
just
return longproceshere()中是否真的需要异步/wait?我知道如果以后添加更多的代码,异常处理将是一个工厂,但如果这就是方法所做的全部,我不确定是否需要它。@LasseVågsætherKarlsen这取决于
myasynchmethod
中实际发生的情况,我们不能只知道模拟调用,那么LongProcessHere方法内部会发生什么呢?我们需要调用Task.Run让它返回一个任务吗?@user2964556你能编辑你的问题吗?这样就知道什么是
longproceshere()
?我们不能猜测