C# 回不来
我有一个WebApi控制器,它在异步模式下调用第三方API。 一切正常,现在我想在一个单独的操作方法中对结果进行排序。 现在,当我调用API时,在DAL中运行“await client.GetAsycn(…)”之后,不会发生带有结果的回调。我错过了什么 这是我的API控制器:C# 回不来,c#,asynchronous,asp.net-web-api,C#,Asynchronous,Asp.net Web Api,我有一个WebApi控制器,它在异步模式下调用第三方API。 一切正常,现在我想在一个单独的操作方法中对结果进行排序。 现在,当我调用API时,在DAL中运行“await client.GetAsycn(…)”之后,不会发生带有结果的回调。我错过了什么 这是我的API控制器: // GET api/lookup [ResponseType(typeof(RestaurantModel))] public async Task<IHttpActionResult>
// GET api/lookup
[ResponseType(typeof(RestaurantModel))]
public async Task<IHttpActionResult> Get(string outcode)
{
if (string.IsNullOrEmpty(outcode)) throw new ArgumentNullException(nameof(outcode));
var result = await _repository.GetRestaurantsByOutcode(outcode);
return Ok(new RestaurantModel()
{
Result = result
});
}
// GET api/sorted
[System.Web.Http.Route("~/api/sorted")]
public List<Restaurant> GetSorted(string outcode)
{
if (string.IsNullOrEmpty(outcode)) throw new ArgumentNullException(nameof(outcode));
return _repository.GetSortedRestaurantsByOutcode(outcode);
}
//获取api/查找
[ResponseType(类型(RestaurantModel))]
公共异步任务获取(字符串输出代码)
{
if(string.IsNullOrEmpty(outcode))抛出新的ArgumentNullException(nameof(outcode));
var result=await_repository.GetRestaurantsByOutcode(outcode);
返回Ok(新RestaurantModel()
{
结果=结果
});
}
//获取api/排序
[System.Web.Http.Route(“~/api/sorted”)]
公共列表GetSorted(字符串输出代码)
{
if(string.IsNullOrEmpty(outcode))抛出新的ArgumentNullException(nameof(outcode));
return _repository.getSortedRestaturantsByOutCode(outcode);
}
这是我的存储库,使用新方法对结果进行排序:
public class RestaurantRepository : IRestaurantRepository
{
private readonly IContext _context;
public RestaurantRepository(IContext context)
{
_context = context;
}
public Task<ApiResult> GetRestaurantsByOutcode(string outcode)
{
return _context.GetRestaurantsByOutcode(outcode);
}
public List<Restaurant> GetSortedRestaurantsByOutcode(string outcode)
{
return _context.GetRestaurantsByOutcode(outcode).Result.Restaurants
.OrderBy(x => x.Name).ToList();
}
}
public class RestaurantRepository:IRestaurantRepository
{
私有只读IContext\u上下文;
公共餐厅位置(IContext上下文)
{
_上下文=上下文;
}
公共任务GetRestaurantsByOutcode(字符串outcode)
{
返回_context.GetRestaurantsByOutcode(outcode);
}
公共列表GetSortedRestaturantsByOutCode(字符串outcode)
{
return\u context.GetRestaurantsByOutcode(outcode).Result.Restaurants
.OrderBy(x=>x.Name).ToList();
}
}
这是我调用第三方API的DAL:
public async Task<ApiResult> GetRestaurantsByOutcode(string outcode)
{
using (var client = new HttpClient())
{
ConfigureHttpClient(client);
var response = await client.GetAsync(
$"restaurants?q={WebUtility.UrlEncode(outcode)}");
return response.IsSuccessStatusCode
? await response.Content.ReadAsAsync<ApiResult>()
: null;
}
}
公共异步任务GetRestaurantsByOutcode(字符串outcode)
{
使用(var client=new HttpClient())
{
配置HttpClient(客户端);
var response=await client.GetAsync(
$“餐厅?q={WebUtility.UrlEncode(outcode)}”);
返回响应。IsSuccessStatusCode
?等待响应。Content.ReadAsAsync()
:null;
}
}
有时使用async/await,有时不使用async/await,这是一种混合匹配。Async/await(默认情况下是can和do)确保调用线程上的调用继续,从而生成上下文。您需要对代码进行allign,以便在整个堆栈中使用async/await。否则你就是在给自己制造僵局
[System.Web.Http.Route("~/api/sorted")]
// missing async in signature (not good if you are calling it with await in your controller)
public async Task<List<Restaurant>> GetSorted(string outcode)
{
if (string.IsNullOrEmpty(outcode)) throw new ArgumentNullException(nameof(outcode));
// added await in call
return await _repository.GetSortedRestaurantsByOutcode(outcode);
}
[System.Web.Http.Route(“~/api/sorted”)]
//签名中缺少async(如果在控制器中使用wait调用它,则不太好)
公共异步任务GetSorted(字符串输出代码)
{
if(string.IsNullOrEmpty(outcode))抛出新的ArgumentNullException(nameof(outcode));
//增加了等待电话
返回等待存储库。GetSortedRestaturantsByOutCode(outcode);
}
达尔
public class RestaurantRepository:IRestaurantRepository
{
私有只读IContext\u上下文;
公共餐厅位置(IContext上下文)
{
_上下文=上下文;
}
//添加了异步和等待
公共异步任务GetRestaurantsByOutcode(字符串outcode)
{
return wait_context.GetRestaurantsByOutcode(outcode);
}
//添加了异步和等待
公共异步任务GetSortedRestaturantsByOutCode(字符串outcode)
{
//在这里,您没有使用await,而是使用result,即使您调用了一个标记为async的方法,该方法又使用了await。这是您死锁的地方,但这是修复方法。
return(wait_context.GetRestaurantsByOutcode(outcode)).Restaurants
.OrderBy(x=>x.Name).ToList();
}
}
public class RestaurantRepository : IRestaurantRepository
{
private readonly IContext _context;
public RestaurantRepository(IContext context)
{
_context = context;
}
// added async and await
public async Task<ApiResult> GetRestaurantsByOutcode(string outcode)
{
return await _context.GetRestaurantsByOutcode(outcode);
}
// added async and await
public async Task<List<Restaurant>> GetSortedRestaurantsByOutcode(string outcode)
{
// here you were not using await but then using result even though you were calling into a method marked as async which in turn used an await. this is where you deadlocked but this the fix.
return (await _context.GetRestaurantsByOutcode(outcode)).Restaurants
.OrderBy(x => x.Name).ToList();
}
}