Асинхронная проблема при изменении метода использования коллекции

У меня был такой метод:

public async Task<IEnumerable<Model>> Get(string link)
{
   MyRequestAsync request = new MyRequestAsync(link);
   return await request.GetResult();
}

Это работает очень хорошо.

Тогда я решил немного изменить это:

public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links)
{
    IList<Model> list = new List<Model>();
    foreach (var link in links)
    {
        MyRequestAsync request = new MyRequestAsync(link);
        list.Add(await request.GetResult());
    }

    return list;
}

И теперь у меня проблема, по какой-то причине он просто не возвращает результат. Насколько я понимаю, я получаю тупик.

Вы знаете, как это исправить?


person sreginogemoh    schedule 17.04.2014    source источник
comment
возможный дубликат Можно ли ожидать yield return DoSomethingAsync()   -  person Fals    schedule 17.04.2014
comment
@Fals, похоже, это не связано. Он не использует доходность.   -  person Matt Smith    schedule 17.04.2014
comment
Если вы опубликуете небольшой, но полный пример, воспроизводящий проблему, мы сможем помочь вам лучше.   -  person Matt Smith    schedule 17.04.2014
comment
Приостановите отладчик, чтобы увидеть, что находится в стеке. Были ли приостановлены казни? Вероятно, какой-то блокирующий код в GetResult.   -  person usr    schedule 17.04.2014
comment
Ваш первый метод даже не скомпилируется, так почему же вы говорите, что он работает?   -  person svick    schedule 17.04.2014
comment
Это не похоже на тупик, попробуйте передать список только одного URL-адреса и посмотрите, что произойдет.   -  person NeddySpaghetti    schedule 18.04.2014


Ответы (2)


Добавьте ConfigureAwait(false), чтобы избежать взаимоблокировки в потоке пользовательского интерфейса.

public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links)
{
  IList<Model> list = new List<Model>();
  foreach (var link in links)
 {
     MyRequestAsync request = new MyRequestAsync(link);
     list.Add(await request.GetResult().ConfigureAwait(false));
}

return list;
person Yuval Itzchakov    schedule 17.04.2014

Попробуйте это:

IList<Model> list = new List<Model>();

to

ConcurrentBag<Model> list = new ConcurrentBag<Model>();

Часто использование async и await может привести к путанице (по крайней мере, для меня) и привести к результатам, в которых я не уверен. Это первое, что я меняю, когда у меня возникают проблемы.

http://msdn.microsoft.com/en-us/library/dd381779%28v=vs.110%29.aspx

person Ian P    schedule 17.04.2014
comment
Я не думаю, что программирование культа грузов ("Я не знаю, что это делает, но это сработало для меня однажды, так что это может сработать и для вас, даже если ситуация другая») — хорошая практика. И я не вижу причин, по которым это изменение должно здесь помочь. - person svick; 17.04.2014