Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在asp web api中的第二个异步调用中等待异步结果_C#_Asynchronous_Asp.net Web Api - Fatal编程技术网

C# 如何在asp web api中的第二个异步调用中等待异步结果

C# 如何在asp web api中的第二个异步调用中等待异步结果,c#,asynchronous,asp.net-web-api,C#,Asynchronous,Asp.net Web Api,我必须使用第一个异步调用中的结果来调用第二个异步方法,但web api在完成调用方法2之前返回空结果 我尝试过使用.ContinueWith,但出现了死锁 有人能给我一个解决办法吗 例如: public class AsyncApiController : ApiController { [ActionName("GetClientBySSN")] public async Task<IHttpActionResult> GetClientBySSN(string s

我必须使用第一个异步调用中的结果来调用第二个异步方法,但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;
        }
    }
}
公共类AsyncApicController:ApicController
{
[ActionName(“GetClientBySSN”)]
公共异步任务GetClientBySSN(字符串ssn)
{
返回Ok(wait_repository.GetClientBySSN(ssn));
}
}
公共接口IResRepository
{
任务GetClientBySSN(字符串ssn);
}
公共类存储库:IResRepository
{
公共任务GetClientBySSN(字符串ssn)
{
//异步方法
任务task1=_service.GetClientNumberBySSN(ssn);
int clientNumber=task1.Result.clientNumber;
if(clientNumber!=null)
{
//使用第一个结果的ID的另一个异步方法
return _service.GetClientDetailsByClientNumber(clientNumber);
}
其他的
{
返回null;
}
}
}

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

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

公共类ResRepository:IResRepository
{
//缺少异步
公共异步任务GetClientBySSN(字符串ssn)
{
//缺少等待-也可以使用等待并直接获取结果,而不是获取任务然后等待
var client=wait_service.GetClientNumberBySSN(ssn);
//类型int永远不能为null,这将永远不会计算为false。也许你是指上面的int
//我改为客户端空检查,也许这就是你想要的
如果(客户端!=null)
{
//使用第一个结果的ID的另一个异步方法
//更改-缺少等待
返回wait_service.GetClientDetailsByClientNumber(client.clientNumber);
}
其他的
{
返回null;
}
}
}


另外,命名使用wait/async并带有后缀
async
的方法也是一种很好的做法。因此,
GetClientDetailsByClientNumber
将成为
GetClientDetailsByClientNumberAsync
GetClientBySSN
将成为
GetClientBySSNAsync
。这使调用方更清楚地了解代码的实现细节。

如果您使用的是web api或更一般的网络应用程序服务,请区分客户端和服务器端

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

第二点与异步api的影响有关,这意味着客户机基础设施应该收到请求完成的通知,因此有一个接收此类通知的通道,必须在客户机端打开,并且在该接口的设计过程中不可能完全明显。所以我还是会选择一个只有客户端的异步版本的接口,除非有明确的、不同的体系结构需求

最后一点,回到您的问题,以防您刚刚用经典的async-Wait修复了代码

99%的情况下,wait Foo()应该是wait Foo()。configurewait(false)

您的案例似乎处于无上下文的情况下

int clientNumber=(wait task1)。当您可以等待时,不要使用
Task.Result
阻止任务。
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;
        }
    }
}