Synchronous implementation of interface that returns Task

前端 未结 3 1377
猫巷女王i
猫巷女王i 2020-12-01 19:51

Similar to Implementing an interface that requires a Task return type in synchronous code although I\'m curious if I should just ignore the compiler error my situation gener

3条回答
  •  温柔的废话
    2020-12-01 19:57

    As everybody else already pointed out, you have 3 different options, so it's a matter of opinion:

    1. keep it async and ignore the warning
    2. have sync/async overloads
    3. remove async and return a completed task.

    I would recommend returning an already completed task:

    public class SimplyAwesome : IAmAwesome 
    {
        public Task MakeAwesomeAsync() 
        {
            // run synchronously
            return TaskExtensions.CompletedTask;
        }
    }
    

    For several reasons:

    • Making a method async has a slight overhead of creating a state-machine and disabling some optimizations (like inlining) because of the try-catch block the compiler adds.
    • You need to deal with the warning and with any other team-member looking at this code wondering where the await is.
    • There's somewhat of a dissonance in marking a completely synchronous method async. It's like adding while(false){} in your code, it will act the same, but it doesn't convey the meaning of the method.

    Servy pointed out that returning a task changes the semantics of exception handling. While that's true, I think it's a non-issue.

    First of all, most async code calls a method and awaits the returned task at the same place (i.e. await MakeAwesomeAsync()) which means the exception would be thrown at the same place no matter whether the method was async or not.

    Second of all, even the .Net framework's Task-returning methods throw exceptions synchronously. Take for example Task.Delay which throws an exception directly without storing it in the returned task, so there's no need to await the task to raise the exception:

    try
    {
        Task.Delay(-2);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
    

    Since .Net developers need to except to encounter exceptions synchronously in .Net it's reasonable they should also except that from your code.

提交回复
热议问题