Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert void into async return in C#

Tags:

c#

async-await

I read that returning void from a C# async call is not good. But I have the following scenario:

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)
}

Since I just want that function be executed with no return at all. Should i keep it like this, or should I return Task from DoSomething()? If I change it to return Task, since my code doesn't need to return anything at all, what should I return?

like image 200
Kirzy Avatar asked Sep 01 '15 12:09

Kirzy


2 Answers

If i change it to return Task, since my code need return nothing at all, what should i return?

Your current code wouldn't compile, as you can't await on a void returning method (because it doesn't return an awaitable, which is a type which exposes a GetAwaiter method).

Any void method in the synchronous world should return a Task in the asynchronous world. This allows for anyone who wishes to asynchronously wait on the async operation, and also gets a chance to handle exceptions properly. using async void means that the exception will either be swallowed, or if set to in the configuration, will be rethrown on an arbitrary threadpool thread. Async should be propagated properly all the way.

Note that when you await both operations in MainFunctionAsync, you're not firing and forgetting, you're asynchronously waiting for each of them to complete, sequentially.

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

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

public Task DoSomethingMoreAsync()
{
    // Do more meaningful async stuff
}
like image 129
Yuval Itzchakov Avatar answered Sep 16 '22 14:09

Yuval Itzchakov


you can return either of these

Task.FromCompleted;
Task.FromException(ex);

so your method would be like this:

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);
   }
}
like image 26
Simple Fellow Avatar answered Sep 16 '22 14:09

Simple Fellow