Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous method that does nothing

Tags:

I have an interface IAnimation which exposes a method BeginAsync(). That method should start the animation and return when it is completed.

What I would like to do is implement a null animation class NoAnimation that just returns when it executes BeginAsync().

Is this the right implementation?

public async Task BeginAsync() {     await Task.Run(() => { }); } 

I suspect that there is a more elegant approach than this. I also considered creating an empty method. But that gives me a warning which I don't like either.

like image 737
Fabio Marcolini Avatar asked May 13 '13 15:05

Fabio Marcolini


People also ask

Can an async function return nothing?

Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.

What happens if we execute an asynchronous method but don't await it?

What if you don't use await with async ? The call meant to be Asynchronous becomes Synchronous and would immediately impact the system scalability, as threads are now blocked, even worse for a long running IO operations.

Should all methods be async?

If a method has no async operations inside it there's no benefit in making it async . You should only have async methods where you have an async operation (I/O, DB, etc.). If your application has a lot of these I/O methods and they spread throughout your code base, that's not a bad thing.

How do you call async method without await?

However, just to address "Call an async method in C# without await", you can execute the async method inside a Task. Run . This approach will wait until MyAsyncMethod finish. await asynchronously unwraps the Result of your task, whereas just using Result would block until the task had completed.


2 Answers

Just use Task.CompletedTask to return a completed task:

public Task BeginAsync() {      return Task.CompletedTask; } 

If you have a Task<TResult> use Task.FromResult<TResult> to return a completed task with a result:

public Task<bool> BeginAsync() {      return Task.FromResult(true); } 

Your current implementation is very inefficient, as it builds the state machine, and also uses a ThreadPool thread to run the empty task.

like image 59
Reed Copsey Avatar answered Oct 19 '22 11:10

Reed Copsey


It's very easy to fall into the trap of thinking that async must be part of the signature of any asynchronous method. It looks it must be; it (misleadingly!) reads as if it's whole purpose is to mark a method as asynchronous.

But it's not, Task or Task<T> are required, but not async. This is shown in @ReedCopsey's answer and in the following example (slightly adapted from this useful SO answer):

public Task<int> MethodTaskAsync(int arg0, int arg1) {     Task<int> task = new Task<int>(() => Method(arg0, arg1));     task.Start(); // Hot task (started task) should always be returned.     return task; } 

That's why interface method signatures don't need, and can't have, the async keyword: an 'asynchronous' method per se, without regard to how it might be implemented, is just a method that returns a started (and, possibly, already finished) Task or Task<T>.

If async doesn't mark a method as asynchronous, what does it do? It's a way to write asynchronous methods more simply: once you have applied it to a method, you can use the await keyword to tell the compiler to correctly handle subsidiary asynchronous calls for you very simply (without it, you could try to handle subsidiary Tasks manually, using lots more code like that in the code block above, but to do so would be very complex and error prone).

So if you just want to return a do-nothing, already-completed task from an 'asynchronous' (i.e. Task-returning) method, you can and should do so synchronously(!), as in @ReedCopsey 's answers, using Task.CompletedTask or Task.FromResult(...).

like image 34
MikeBeaton Avatar answered Oct 19 '22 12:10

MikeBeaton