在C#中将void转换为异步返回

Kir*_*rzy 4 c# async-await

我读到void从C#async调用返回并不好.但我有以下情况:

public async void MainFunction()
{
    await DoSomething()
    await DoSomethingMore()
}

public void DoSomething() 
{
    //some code that I want to execute (fire and forget)
}

public void DoSomethingMore()
{
    //some code that I want to execute (fire and forget)
}
Run Code Online (Sandbox Code Playgroud)

因为我只想要执行该函数而根本没有返回.我应该这样保留它,还是应该Task从DoSomething()返回?如果我将其更改为返回Task,因为我的代码根本不需要返回任何内容,我应该返回什么?

Yuv*_*kov 8

如果我改变它以返回任务,因为我的代码需要什么都不返回,我应该返回什么?

您当前的代码将无法编译,因为您无法awaitvoid返回的方法上进行编译(因为它不会返回等待的,这是一种公开GetAwaiter方法的类型).

void同步世界中的任何方法都应该Task在异步世界中返回a .这允许任何希望异步等待异步操作的人,并且还有机会正确处理异常.使用async void意味着将吞下异常,或者如果在配置中设置为异常,则将在任意线程池线程上重新抛出异常.异步应该一直正常传播.

请注意,当您等待两个操作时MainFunctionAsync,您不会触发并忘记,您将异步地等待每个操作按顺序完成.

public async Task MainFunctionAsync()
{
    await DoSomethingAsync();
    await DoSomethingMoreAsync();
}

public Task DoSomethingAsync() 
{
    // Do meaningful async stuff
}

public Task DoSomethingMoreAsync()
{
    // Do more meaningful async stuff
}
Run Code Online (Sandbox Code Playgroud)


Sim*_*low 5

您可以返回其中任何一个

Task.FromCompleted;
Task.FromException(ex);
Run Code Online (Sandbox Code Playgroud)

所以你的方法会是这样的:

public void MainFunction()
{
    await DoSomething()
    await DoSomethingMore()
}

public Task DoSomething() 
{
    try{

     //some code that I want to execute (fire and forget)

     return Task.FromCompleted;
   }
   catch(Exception ex){
     return Task.FromException(ex);
   }

}


    //some code that I want to execute (fire and forget)
}

public Task DoSomethingMore()
{
       try{

     //some code that I want to execute (fire and forget)

     return Task.FromCompleted;
   }
   catch(Exception ex){
     return Task.FromException(ex);
   }
}
Run Code Online (Sandbox Code Playgroud)