简体   繁体   English

异步等待方法卡住

[英]Async await method gets stuck

I have an API method with this signature:我有一个带有这个签名的 API 方法:

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....在调试模式下,我看到我的代码进入StartAsync并返回并完成它,但看起来等待永远不会结束......

I have no idea what it can be.我不知道它会是什么。

If you need more information about my code, let me know.如果您需要有关我的代码的更多信息,请告诉我。

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 (ie 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:您仍然可以使方法async并像同步方法一样返回响应,如下所示:

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.但这可能会触发 Intellisense 告诉您在您的方法中没有任何等待。 A better approach is to use Task.FromResult like so:更好的方法是像这样使用Task.FromResult

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.这将返回一个已经完成的任务,因此不会阻止您在后续操作中await

You are creating a task by calling the Task Constructor您正在通过调用任务构造函数来创建任务

This creates a Task , but does not start it.这会创建一个Task ,但不会启动它。 You would have to explicitly call Task.Start您必须显式调用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();
   }

You have other options here.您在这里还有其他选择。 You can create the object on the current thread and return it as a completed task您可以在当前线程上创建 object 并将其作为已完成的任务返回

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

Another option is to invoke Task.Run to kick off the work on a background thread.另一种选择是调用Task.Run来启动后台线程上的工作。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM