我必须在第一次异步调用中使用结果来调用第二个异步方法但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;
}
}
}
答案 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
将成为GetClientDetailsByClientNumberAsync
而GetClientBySSN
将成为GetClientBySSNAsync
。这使得代码的实现细节对于调用者来说更清楚。
答案 1 :(得分:0)
如果您使用的是网络应用服务,或者更常见的是网络应用服务,请区分客户端和服务器端。
首先,您不需要异步api来使您的客户端异步:双方完全独立。所以,我最初的建议是你可能只想让客户端异步并将web api维护为服务器上的同步调用(当然可以有一个应用程序主机框架负责实现调用,负载平衡等等)。
第二点与异步api的影响有关,这意味着应该通知客户端基础结构请求完成,因此有一个通道可以接收必须在客户端打开的通知,在设计这个界面时,这一点并不完全明显。所以,除非有明确的,不同的架构要求,否则我将再次使用客户端的异步版本。
最后一点,回到你的问题,以防你用经典的异步修复代码 - 等待一直......
99%的时间,等待Foo()应等待Foo()。ConfigureAwait(false)
你的案子似乎属于无环境的情况