Is it wrong to return null in a task?

Asked

Viewed 177 times

-1

I have the following implementation of MemoryCache:

public Task<News[]> GetCandidateNewsAsync(string candidate)
{
    return _cache.GetOrCreateAsync(candidate, async factory =>// _cache é um IMemoryCache
    {
        var candidateUri = _candidateUris[candidate];

        if (string.IsNullOrEmpty(candidateUri))
            return null; //retorno nulo aqui (erro)

        var candidateNews = await _candidateNewsClient.GetCandidateNewsAsync(1, candidateUri);

        return candidateNews?.News;
    });
}

I ran a code analyzer on top of my project and it reported the following:

Do not Return null from this method, Instead Return 'Task.Fromresult(null)', 'Task.Completedtask' or 'Task.Delay(0)'

Only that I did not understand right, what is the problem of returning null on this occasion? What is the sense of returning a delay of 0ms as he recommends?

  • You could put the method header?

  • Done @Maniero ;)

2 answers

1


That’s an answer withdrawal of the Soen:

It’s not right to return a Task null. A Task nulla is as if she had never been called, but she was.

So a Task/Task<T> returned from a method should never be null. But still you can return the null value within the Task.


What is the problem of returning null on this occasion?

In my case, it was probably a false alarm from my analyzer, since I was not returning to Task as null, and yes the null value within the Task, which is totally correct.

Explaining better, the method GetOrCreateAsync of IMemoryCache receives a generic type as a parameter(<T>), and a Func<ICacheEntry, out Task<T>>, and as my task was asynchronous, when I returned null, it was not returning to Task as null, and yes the value within the Task, of the kind News[] null.


What sense to return a delay of 0ms as he recommends?

A Task.Delay of 0ms is the same thing as returning a Task.CompletedTask, see how it is implemented in official code of : (line 5407 at the time I am writing)

public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken)
{
    // ...
    if (cancellationToken.IsCancellationRequested)
    {
        // return a Task created as already-Canceled
        return Task.FromCanceled(cancellationToken);
    }
    else if (millisecondsDelay == 0)
    {
        // return a Task created as already-RanToCompletion
        return Task.CompletedTask;
    }
    // ...
}

0

Semantically speaking, it makes no sense for a Task Force to return null. In the world of asynchronous execution, you return null is 'as if you had spoken' to code that a task has not been executed or does not exist, but in your case it does exist.

The mistake is telling you to make the Task return a value null (TaskFromReult(null)) or else returning that the task was executed (Task.CompletedTask).

This is all because this is how you normally use tasks, it’s part of good practice. When you perform an asynchronous task, you expect it to return whether it was executed or not, you don’t expect it to be null. Think that this type of analysis is for other people who may come to use your code in the future.

  • You can put how his code would look?

  • Just exchange return null for return Task.FromResult(null) .

  • Added the @Maniero example

  • @Francisco this is because the method needs to return a vector of the type News[], did not have this information previously had? So you need to return something of the same type. You can try something like: Create a vector of the type News worthwhile null and return it. News[] nw = null return return Task.FromResul(nw). This should work. Task.Delay(0) : according to the MS reference, it performs the Task.CompletedTask when the time is equal to 0ms. You can see more here

  • Dude, I made a little test program here and it worked.. link

Browser other questions tagged

You are not signed in. Login or sign up in order to post.