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; use await instead.
  • Do not use ContinueWith; use await 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 returning Task.CompletedTask
  • if your function returns a Task<T> return a completed task of T, which can be done with Task.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 a Task or Task<T>, you need to create the task explicitly, and there is the danger of returning null instead of a task.
  • in an async function that returns a Task or Task<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 returning null.