Create a completed Task

前端 未结 8 1895
名媛妹妹
名媛妹妹 2020-11-28 06:13

I want to create a completed Task (not Task). Is there something built into .NET to do this?

A related question: Create a complete

相关标签:
8条回答
  • 2020-11-28 06:45

    You can use Task.FromResult (in .NET 4.5) to return a completed Task<T>.

    If you need a non-generic Task, you can always use Task.FromResult(0) or similar, since Task<T> is a subclass of Task.

    0 讨论(0)
  • 2020-11-28 06:50

    Task<T> is implicitly convertable to Task, so just get a completed Task<T> (with any T and any value) and use that. You can use something like this to hide the fact that an actual result is there, somewhere.

    private static Task completedTask = Task.FromResult(false);
    public static Task CompletedTask()
    {
        return completedTask;
    }
    

    Note that since we aren't exposing the result, and the task is always completed, we can cache a single task and reuse it.

    If you're using .NET 4.0 and don't have FromResult then you can create your own using TaskCompletionSource:

    public static Task<T> FromResult<T>(T value)
    {
        var tcs = new TaskCompletionSource<T>();
        tcs.SetResult(value);
        return tcs.Task;
    }
    
    0 讨论(0)
  • 2020-11-28 06:51

    The newest version of .Net (v4.6) is adding just that, a built-in Task.CompletedTask:

    Task completedTask = Task.CompletedTask;
    

    That property is implemented as a no-lock singleton so you would almost always be using the same completed task.

    0 讨论(0)
  • 2020-11-28 06:56

    I would use Task.Delay(0). Internally, it returns a cached instance of a completed Task<T>. This is exactly what the current answer suggest doing anyway, only now you don't have to cache an instance yourself, nor do you have any inelegant garbage values in your code.

    You might be thinking you can use Task.Yield() instead, but it turns out the result of Task.Yield() is not a subtype of Task, whereas the result of Task.Delay(0) is. That's one of the subtle differences between the two.

    0 讨论(0)
  • 2020-11-28 07:00

    My preferred method for doing this is to call Task.WhenAll() with no arguments. The MSDN documentation states that "If the supplied array/enumerable contains no tasks, the returned task will immediately transition to a RanToCompletion state before it's returned to the caller.". That sounds like what you want.

    Update: I found the source over at Microsoft's Reference Source; there you can see that Task.WhenAll contains the following:

    return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
                Task.CompletedTask :
                new WhenAllPromise(tasks);
    

    So Task.CompletedTask is indeed internal, but it is exposed by calling WhenAll() with no arguments.

    0 讨论(0)
  • 2020-11-28 07:00

    How about:

    #pragma warning disable 1998
        public async Task emptyTask() {
        }
    #pragma warning restore 1998
    

    You can leave out the warning suppression if you don't mind it.

    0 讨论(0)
提交回复
热议问题