无法等待ASP.NET(4.6)MVC5项目

时间:2015-05-06 23:52:34

标签: c# asp.net unit-testing asp.net-web-api async-await

我目前正在看一个问题,即我的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

有趣的是,如果我在“PlaceManager”单元测试中运行完全相同的代码,在Web API项目之外,测试运行正常,我可以检查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方法中可能会发生这种情况,但在单元测试中工作正常?

1 个答案:

答案 0 :(得分:1)

如上面的Alexei Levenkov所述,我使用getDataAsync().Result代码导致死锁。

在将Place对象映射到MapPlaceDTO对象时,Place对象有一个get属性来加载场所类型,它将通过以下方式调用异步函数:

public PlaceType PlaceType
{
    get
    {
        return getPlaceType().Result;
    }
}

一旦我删除了该属性并直接使用await关键字调用了GetPlaceType方法,一切都开始正常工作。谢谢阿列克谢!