hedbisker
hedbisker

Reputation: 327

Async await method gets stuck

I have an API method with this signature:

public Task<MResponse> StartAsync(MRequest request)

I can't change that (I can change the implementation inside but not the signature of the method).

This is how I call this method:

var ret = await _SyncClient.StartAsync(Request);

This is the implementation

  public Task<MResponse> StartAsync(MRequest request)
  {
       if (request.Number == 1)
       {
            return new Task<MResponse>(() => new MResponse() { Description = "Error", Code = 1 });
       }
       else
       {
            return new Task<MResponse>(() => new MResponse() { Description = "", Code = 0 });
       }
   }

On the debug mode I see that my code get into StartAsync and and the return and finish it, but its look like the wait never ends....

I have no idea what it can be.

If you need more information about my code, let me know.

Upvotes: 0

Views: 2846

Answers (2)

Andrew Shepherd
Andrew Shepherd

Reputation: 45252

You are creating a task by calling the Task Constructor

This creates a Task, but does not start it. You would have to explicitly call Task.Start

public Task<MResponse> StartAsync(MRequest request)
{
       var task = (request.Number == 1)
           ? new Task<MResponse>(() => new MResponse() { Description = "Error", Code = 1 })
           : new Task<MResponse>(() => new MResponse() { Description = "", Code = 0 });
       task.Start();
       return task;
}

You have other options here. You can create the object on the current thread and return it as a completed task

return Task.FromResult<MResponse>(new MResponse(...))

Another option is to invoke Task.Run to kick off the work on a background thread.

public Task<MResponse> StartAsync(MRequest request)
{
       Func<MResponse> generateResponse = (request.Number == 1)
           ? () => new MResponse() { Description = "Error", Code = 1 })
           : () => new MResponse() { Description = "", Code = 0 });
       return Task.Run(generateResponse);
}

Upvotes: 1

Dave Van den Eynde
Dave Van den Eynde

Reputation: 17415

It looks like you're not actually having anything asynchronous to do in the implementation. That's fine, there's always cases where the signature is set (i.e. an interface) and some implementations don't need it.

You can still make the method async and just return the response as if it were as synchronous method, like so:

public async Task<MResponse> StartAsync(MRequest request)
{
    return new MResponse() { ... }
}

But that will probably trigger Intellisense to tell you there's nothing being awaited in your method. A better approach is to use Task.FromResult like so:

public Task<MResponse> StartAsync(MRequest request)
{
    return Task.FromResult(new MResponse() ... );
}

which will return a Task that already as completed and therefore will not block your await in the follow-up.

Upvotes: 3

Related Questions