Is adding async to a method signature a violation?

When referring to the question of how much to use async / await, i.e. "should all methods return Task

?" by the author of this answer , MatΓ­as Fidemraizer, states that even if your method is currently only running synchronously, it should still return a task, so if you do it later as "asynchronous" "you can turn it into real asynchronous operations without affecting your entire codebase." It makes sense, but if I'm really expecting something, I have to add async

to the method signature. So we're talking about going from:

public Task WhateverAsync()
{
    return Task.FromResult(true);
}

      

to

public async Task WhateverAsync()
{
    return await AwaitableSomething();
}

      

Does it async

add an interrupt violation to the method signature?

+3


source to share


2 answers


even if your method is currently only running synchronously, it should still return the task

I disagree. If your method is synchronous, then it must have a synchronous API. If your method is asynchronous then it should have an asynchronous API.

However, I would agree that synchronous methods should have a Task

-signature if they are defined in the interface / base class and there is a decent possibility that future implementations / overrides might want to use await

.

Adds async to the method signature of the interrupt violation?



Just adding async

? Not. Consider the case of an Task

-return method defined in an interface: it can be implemented either with or without async

.

However, there are several possible semantics differences as I describe in my blog. Most notably, exception handling is different. If you're not careful, a naive synchronous implementation can throw an exception directly rather than returning a faulty task. Once you do this method async

, the exception will fail the task and will no longer be thrown directly.

So this is really a question about possible changes in semantics. I would argue that the naive synchronous semantics were wrong since the method had an asynchronous signature. For example, a synchronous method has an asynchronous signature, so it is reasonable for callers to assume that it will catch exceptions and return a faulty task. So, if synchronous implementations have these (easy-to-reason) bugs, then the addition async

would be technically a change.

+6


source


No, this is not (really) a violation. Adding a keyword async

to a method is just a hint for the compiler to turn it into an asynchronous state machine.

I am using the following code to validate the public signature of a method in LINQPad.

var method = typeof(ContainingClass).GetMethod("WhateverAsync");
method.ReturnType.Dump();
method.GetParameters().Length.Dump();
method.GetCustomAttributes().Dump();

      

The first two dumps return the following for both of your methods.



System.Threading.Tasks.Task
0

      

A value means they return the same value type and take the same number of parameters. However, they have different attributes, which is technically a violation of the change (but if the code really depends on it, it's garbage code).

The first method has no custom attributes, and the second method has the following two attributes: AsyncStateMachineAttribute

and DebuggerStepThroughAttribute

.

Something else you want to be aware of when dealing with reflection is that adding a keyword async

to a method adds a nested private (generated) class to its containing type, usually called something along the lines <WhateverAsync>d__0

.

+1


source







All Articles