What is the best practice of using async without waiting?

Application

I have a View Model referenced by several projects or Views .

Due to the API, some of the View projects are asynchronous, while others are not.

The View project implements an interface implementation in the View Model using the IOC container.

The code

Consider this minimal code example.

Interface:

 public interface IDatabase { Task<Data> GetData(); } 

View Model expects the GetData method:

 pubic class DisplayDataViewModel { private readonly IDatabase _database public DisplayDataViewModel(IDatabase database) { _database = database; } private async Task GetDataFromDatabase() { Data data = await _database.GetData(); // do something with data... } } 

Asynchronous View The project uses the Async function to receive data.

 public class AsynchronousViewDataBase : IDatabase { public async Task<Data> GetData() { return await GetDataAsync(); } } 

Synchronous View The project uses a synchronous call to retrieve data, but due to interface limitations I need to return the task, but I'm just interested in returning Data , which results in the async method.

 public class SynchronousViewDatabase : IDatabase { public async Task<Data> GetData() { return GetData(); } } 

But , then he gives a warning:

In this asynchronous method, there are no “wait” statements and will be executed synchronously. Think about how to use the “wait” operator to wait for non-blocking API calls or “wait for Task.Run (...)” to do the work of binding to the processor in the background thread.

What doesn’t matter to me, since I don’t care if it works synchronously.

Using Task.Run to suppress a warning seems unnecessary because the call (and in my case) comes from a background thread.

Question

Is there any best practice for implementing this type of non-expecting asynchronous method? Can a warning be ignored? Is there a better way to implement async synchronous call?

Additional

I converted the interface to a synchronous call and used Task.Result in Asynchronous View (which fixed the warning), but this caused the application to stop responding and there were just a lot of difficult problems.

Note. I am not stating that using the async magically causes the method to run asynchronously.

+7
multithreading c # asynchronous async-await
source share
3 answers

async is an implementation detail, so you can remove it from the method if you are not using await , then you can use Task.FromResult to return an already completed task with the desired result.

 public class SynchronousViewDatabase : IDatabase { public Task<Data> GetData() { return Task.FromResult<Data>(GetData()); } } 
+9
source share

Is there a best practice for implementing this type of non-expecting asynchronous method?

Yes, it is called a synchronous API . Do not force code that is not natural asynchronous. Add a GetData method that returns a string .

Can a warning be ignored?

This is normal if you understand the consequences. Calling a synchronous method, which can be lengthy from an asynchronous method, is likely to surprise consumers of this method, since it actually blocks. In addition, there is the fact that any exception will be encapsulated using the generated Task states. And, of course, the small overhead costs of the state apparatus itself and any operators raised.

Is there a better way to implement async synchronous call?

It really depends on the use case. If this was a short operation that is not noticeable, you can avoid using Task.FromResult and removing the async modifier (as others have said) or defer a call to the thread pool thread. From your question, I understand that you do not want this.

+5
source share

Two different methods should be implemented in your interface, and let the caller decide if he needs asynchronous or synchronizing

 Data GetData(); 

and

 Task<Data> GetDataAsync(); 

here is a possible way to run your synchronous asynchronous method

 public class SynchronousViewDatabase : IDatabase { public Data GetData() { var getDataTask = GetDataAsync(); getDataTask.RunSynchroniously(); if(getDataTask.Status == TaskStatus.RanToCompletion) return getDataTask.Result; throw getDataTask.Exception; } } 
+3
source share

All Articles