【发布时间】:2015-07-17 08:23:59
【问题描述】:
我目前看到一个问题,即我的 await 方法只是挂起,导致响应只是挂起,在我终止请求之前什么都不做。这在 Chrome 调试工具和 Fiddler 中都很明显。
我定义了以下 API 操作:
[Route("state/{stateCode}")]
[LogApiCallFilter]
public async Task<IList<MapPlaceDTO>> GetWithinState(string stateCode)
{
//
// Additional code truncated for SO
// Via debugging I know that the 'state' variable below is correct
//
IList<Place> places = await _placeManager.GetPlacesInState(state);
// Instantiate the list of places.
IList<MapPlaceDTO> mapPlaces = new List<MapPlaceDTO>();
// Iterate through the places and add to the map place list
foreach (Place place in places)
{
mapPlaces.Add(MapPlaceDTO.FromPlace(place));
}
return mapPlaces;
}
当我在调试模式下单步执行该代码以对 GetWithinState 操作进行单元测试时,IList<Place> places = await _placeManager.GetPlacesInState(state); 方法无异常运行,但是我无法将鼠标悬停在 places 变量上进行检查,没有任何反应。我也无法将其添加到监视列表中,我收到以下消息:
error CS0103: The name 'places' does not exist in the current context
然而,有趣的是,如果我在 Web API 项目之外的“PlaceManager”单元测试中运行完全相同的代码,测试运行良好,我可以检查 places 变量。
[Fact(DisplayName = "Can_Get_All_Places_Within_State")]
[Trait("Category", "Place Manager")]
public async Task Can_Get_All_Places_Within_State()
{
State state = new State()
{
ShortName = "VIC",
Name = "Victora",
CountryCode = "AU"
};
IList<Place> places = await _placeManager.GetPlacesInState(state);
Assert.NotNull(places);
Assert.True(places.Count > 0);
}
这是在PlaceManager.GetPlacesInState 方法中运行的代码:
public async Task<IList<Place>> GetPlacesInState(State state)
{
if (state == null)
{
throw new ArgumentNullException("state", "The 'state' parameter cannot be null.");
}
// Build the cache key
string cacheKey = String.Format("places_state_{0}", state.Id);
// Get the places from the cache (if they exist)
IList<Place> places = CacheManager.GetItem<IList<Place>>(cacheKey);
// Get the places from the database.
if (places == null)
{
// Get the places from the database
places = await _repository.Find(i => i.State.ToLower() == state.ShortName.ToLower() && i.Country.ToLower() == state.CountryCode.ToLower());
// If there are places, then add to the cache for next time
if (places != null && places.Count > 0)
{
CacheManager.AddItem(cacheKey, places);
}
}
// return the places
return (places != null ? places : new List<Place>());
}
有谁知道为什么这可能会在 API 方法中发生,但在单元测试中运行良好?
【问题讨论】:
-
挂起时中断并检查所有线程。 93%
Find实际上不是真正的异步方法和某种getDataAsync().Result;代码上的死锁 -
这正是原因。我的 Place 对象有一个 get only 属性,它可以通过以下方式从异步函数中获取地点类型:
get { return getPlaceType().Result; }。我想我需要进一步阅读 async/await 和 .Result 属性。干杯,贾斯汀。
标签: c# asp.net unit-testing asp.net-web-api async-await