Using a typical type as the return type of an asynchronous method

The previous question made me wonder why the following method will raise a compile-time error:

The return type of the asynchronization method must be invalid, Task or Task

public async T MyMethodAsync<T>() where T : Task { // Irrelevant code here which returns a Task } 

Since at compile time it is known that T is always a Task or derived type, why will this not work?

Edit

The reason I'm asking is because the method can return Task or Task<T> . Let them say that the method can return, and I do not want to duplicate the code.

Of course, this is all theoretical and does not apply to production goals.

Edit 2

Lucian Wiskak's excellent article found: Why return an async task

+8
generics c # async-await
source share
2 answers

Three problems:

  • Just because T is a " Task or derived type" does not mean that it is a Task or Task<T> . What would you expect if I called MyMethodAsync<MyCustomTask> , where MyCustomTask comes from Task ?

  • The compiler must know whether it will create a state machine that returns Task or Task<T> when compiling the method - it uses different helper classes in different cases

  • If the async method has a return type of Task , any return cannot specify a value; if it has a return type of Task<T> , any return must specify a value that is implicitly converted to T How does it work in MyMethodAsync ? This is a bit like "my method either void or returns T - you can decide when you call it."

It is not clear what you are trying to achieve here, but in principle this will not work.

+13
source share

I cannot come up with the correct definition of MyMethodAsync , which would allow it to return the general T obtained from Task , not knowing at compile time that this type either accepts any parameter.

If you really return Task or Task<T> , you can update your signature to reflect this fact and avoid the problem.

If you really need some type derived from Task , then you will need to rewrite your logic, instead return Task or Task<T> and wrap around this other type. Assuming this is unacceptable, you will need to reset async and process the state machine yourself.

-one
source share

All Articles