Is it better to return an empty task or null? c#
if it finds no results is it better to return an empty task or null?
There's a couple things to consider here:
First, you should never return a null Task
. In the async
world, a null
task just doesn't make sense. Task
represents the execution of the asynchronous method, so for an asynchronous method to return a null
task is like telling the calling code "you didn't really just call this method" when of course it did.
So, a Task
/Task<T>
returned from a method should never, ever be null
. However, you still have the option of returning a null
value inside a regular task. That is up to you.
with tasks i am unsure which is best.
The task is just a wrapper. The underlying logic is still the same. Think of how this method would look if it were synchronous; would your return type be int
and return 0
if nothing was found, or would your return type be int?
and return null
if nothing was found? After making that choice for a synchronous method, then wrap it in Task<T>
for the asynchronous method.
As a final note, I must say:
- Do not ever, ever use the
Task
constructor. - Avoid
Task<T>.Result
; useawait
instead. - Do not use
ContinueWith
; useawait
instead.
Your method can be drastically simplified:
public virtual async Task<int> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return 0;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}
Or, if you want to return a value (not task) of null
:
public virtual async Task<int?> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return null;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}
If you really want to return null from async method, you can use Task.FromResult(null)
For example:
public async Task<FileInfo> GetInfo()
{
return await Task.FromResult<FileInfo>(null);
}
The answer from Stephen Cleary explains it perfectly: do never return null
, or you'll provoke null reference exceptions but I want to add something:
- if your function returns a
Task
, return a completed task, which can be done by returningTask.CompletedTask
- if your function returns a
Task<T>
return a completed task ofT
, which can be done withTask.FromResult<TResult>(TResult)
If you return null instead of a completed task, this code will throw a null reference exception:
await FunctionThatShouldRetunrTaskButReturnsNull();
and it's a bit difficult to understand what's going on even when you see it in the debugger.
So, never, never, return a null
from a non-async
function that returns a Task
.
Explanation:
- in a non-
async
function, that returns aTask
orTask<T>
, you need to create the task explicitly, and there is the danger of returningnull
instead of a task. - in an
async
function that returns aTask
orTask<T>
, you simply return or return a value, and the result of the function is implicitly converted to a task, so there is no danger of returningnull
.