Is having a return type of Task enough to make a method run asynchronously?

后端 未结 3 1465
悲哀的现实
悲哀的现实 2020-12-12 07:46

I have a simple method that does a complicated string operation and returns the result. As you can see, the return type of this method is Task. Th

3条回答
  •  遥遥无期
    2020-12-12 08:30

    Semantically the method ComplexOperation is asynchronous because it returns an awaitable type, and in order to follow the guidelines it should be named ComplexOperationAsync.

    Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types, such as Task, Task, ValueTask, and ValueTask.

    But it is not a well behaved asynchronous method. An asynchronous method is expected to return an incomplete Task immediately, allowing the caller to await the task asynchronously without been blocked. From the docs:

    An asynchronous method that is based on TAP can do a small amount of work synchronously, such as validating arguments and initiating the asynchronous operation, before it returns the resulting task. Synchronous work should be kept to the minimum so the asynchronous method can return quickly.

    The ComplexOperation method does exactly the opposite: it forces the calling thread to perform the complex operation, and finally it hands back a completed task. For all intents and purposes this operation is not asynchronous at all. It is 100% synchronous and 0% asynchronous, plus some overhead (to add insult to injury). So don't do this, and if there is some library that does it, don't use the library. It is simply bad practice.


    Clarification: Since the term asynchronous method can mean different things in different contexts, I should clarify that the context of this answer is the perspective of the consumer, who sees the signature of the method as a contract, and builds expectations based on the visible contract and not on the invisible implementation. In this context the method ComplexOperation is asynchronous. If we switch perspective and focus on the implementation, the method ComplexOperation is not asynchronous. My statement «it is simply bad practice» refers to the practice of breaking the contract, and providing a synchronous implementation to a method with asynchronous contract. I am not criticizing the use of Task.FromResult method per se. I am criticizing it only when it follows a complex/lengthy/latent operation, that according to the method's contract should be made asynchronous.

    P.S. I am thankful to @DmytroMukalov for providing (in the chat) the helpful distinction between asynchrony by contract and by implementation.

提交回复
热议问题