如何等待async导致asp web api中的第二次异步调用

时间:2016-08-09 18:03:24

标签: c# asynchronous asp.net-web-api

我必须在第一次异步调用中使用结果来调用第二个异步方法但web api在完成调用方法2之前返回空结果?

我尝试过使用.ContinueWith但是出现在死锁中

有人可以引导我找到某种解决方案吗?

示例:

public class AsyncApiController : ApiController
{
    [ActionName("GetClientBySSN")]
    public async Task<IHttpActionResult> GetClientBySSN(string ssn)
    {
        return Ok(await _repository.GetClientBySSN(ssn));
    }
}

public interface IResRepository
{
    Task<ClientResponse> GetClientBySSN(string ssn);
}

public class ResRepository : IResRepository
{
    public Task<ClientResponse> GetClientBySSN(string ssn)
    {
        //async method
        Task task1 = _service.GetClientNumberBySSN(ssn);
        int clientNumber = task1.Result.clientnumber;

        if (clientNumber != null)
        {
            //another async method that uses ID from the first result
            return _service.GetClientDetailsByClientNumber(clientNumber);
        }
        else
        {
            return null;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

您需要在方法签名中添加async,然后在方法调用中添加await关键字。

我标记了您需要更改代码的位置以及代码没有多大意义的位置,例如检查int实例是否为null(您的if语句)。< / p>

public class ResRepository : IResRepository
{
    // missing async
    public async Task<ClientResponse> GetClientBySSN(string ssn)
    {
        // missing await - also use await and get result directly instead of getting the task and then awaiting it
        var client = await _service.GetClientNumberBySSN(ssn);

        // type int can never be null, this will never eval to false. maybe you meant int? above
        // I changed to to client null check instead, maybe that is what you were going for
        if (client != null)
        {
            //another async method that uses ID from the first result
            // change - missing await
            return await _service.GetClientDetailsByClientNumber(client.clientNumber);
        }
        else
        {
            return null;
        }
    }
}

同样,最好使用后缀Async命名使用await / async的方法。因此GetClientDetailsByClientNumber将成为GetClientDetailsByClientNumberAsyncGetClientBySSN将成为GetClientBySSNAsync。这使得代码的实现细节对于调用者来说更清楚。

答案 1 :(得分:0)

如果您使用的是网络应用服务,或者更常见的是网络应用服务,请区分客户端和服务器端。

首先,您不需要异步api来使您的客户端异步:双方完全独立。所以,我最初的建议是你可能只想让客户端异步并将web api维护为服务器上的同步调用(当然可以有一个应用程序主机框架负责实现调用,负载平衡等等)。

第二点与异步api的影响有关,这意味着应该通知客户端基础结构请求完成,因此有一个通道可以接收必须在客户端打开的通知,在设计这个界面时,这一点并不完全明显。所以,除非有明确的,不同的架构要求,否则我将再次使用客户端的异步版本。

最后一点,回到你的问题,以防你用经典的异步修复代码 - 等待一直......

99%的时间,等待Foo()应等待Foo()。ConfigureAwait(false)

你的案子似乎属于无环境的情况