Используйте IComparer асинхронно в C#

Мы обновили нашу кодовую базу, чтобы использовать async/await, но многие ранее работавшие методы теперь дают сбой из-за нового асинхронного кода (частая проблема — HttpContext = null). Я не знаю, как обойти этот метод IComparer.Compare(). Любые идеи? Кажется, я не могу использовать асинхронную задачу в методе сравнения:

public int Compare(myClass x, myClass y)
{
    int someInteger;

    // Standard, boring sorting code here.

    // This is an MVC application calling into an Async method() here...
    var xx = x.CallNewAsyncMethod();
    var yy = y.CallNewAsyncMethod();
    // Work with xx and yy now...
    return someInteger;
}

Если мне не удается сделать этот метод .NET IComparer.Compare() асинхронным, есть ли какие-либо другие альтернативы (например, LINQ), которые я мог бы использовать для сортировки своих классов? Следует отметить одну вещь: я упростил приведенный выше код, но там действительно много всего происходит, и наш код сортировки не является тривиальным. Есть около 10 различных видов сортировки, которые мы могли бы использовать, и каждая сортировка на самом деле представляет собой трехуровневую сортировку (сортировка по a, затем по b, затем по c).

Спасибо за вашу помощь!


person VanAlan    schedule 13.08.2015    source источник
comment
что за штука возвращается?   -  person Daniel A. White    schedule 14.08.2015
comment
это может быть очень дорого - убедитесь, что вы делаете это ленивым и кешируете результаты.   -  person Daniel A. White    schedule 14.08.2015
comment
Я согласен с Даниэлем, если вы используете Sort или OrderBy для этих классов или Contains, то стоимость вызова этого асинхронного метода может быстро стать проблемой.   -  person Travis J    schedule 14.08.2015
comment
@DanielA.White функция возвращает список избранных элементов, отсортированных по дате, цене и т. д. По моим оценкам, у обычного пользователя будет 5-10 избранных, максимум 20.   -  person VanAlan    schedule 14.08.2015


Ответы (2)


многие ранее работающие методы теперь аварийно завершают работу из-за нового асинхронного кода (HttpContext = null является распространенной проблемой).

await будет правильно сохранять HttpContext по умолчанию, поэтому я нахожу эту проблему странной. Убедитесь, что вы используете .NET 4.5, а также нацелены на ASP.NET 4.5 в своем web.config (по умолчанию обновленные проекты будут нацелены на ASP.NET 4.0, который несовместим с await).

Я не знаю, как обойти этот метод IComparer.Compare().

Я впервые слышу, чтобы кто-то проводил асинхронное сравнение. Какая... "интересная"... идея.

Я бы рекомендовал вам не выполнять ввод-вывод или вызовы удаленных служб при сравнении двух объектов в памяти. Если вам нужно выполнить ввод-вывод, сделайте это перед сравнениями. Вы можете хранить результаты ввода-вывода либо в объектах, либо в словаре, отображающем объекты на значения сравнения, либо в виде эфемеронов. Тогда ваш метод Compare работает полностью в памяти и может быть синхронным.

person Stephen Cleary    schedule 14.08.2015
comment
RE: HttpContext Я нахожусь в процессе рефакторинга кода, и я считаю, что эта часть должна быть выполнена, потому что мой код еще не полностью асинхронен для этой конкретной цепочки вызовов. Однако я нахожу странным то, что веб-сайт WebForms не затрагивается новым асинхронным кодом, но мобильный веб-сайт MVC, над которым я работаю, просто застревает, используя тот же код. - person VanAlan; 14.08.2015
comment
RE: IComparer.Compare() Возможно, мой пример кода мог бы быть лучше. Я пытаюсь представить, что старая функция сравнения теперь имеет дело с асинхронной операцией, которая недавно была введена ниже по стеку вызовов. Я согласен, это, вероятно, следует реорганизовать, а не просто переопределить мои методы как асинхронное ожидание. :) - person VanAlan; 14.08.2015

Вы можете сделать метод синхронным, но если вам придется делать это в больших масштабах, это может стать громоздким. Используйте .Wait() после присвоения переменной, чтобы убедиться, что значение заполнено, прежде чем двигаться дальше. Это не потребует, чтобы ваш метод сравнения был помечен как асинхронный.

var xx = x.CallNewAsyncMethod();
xx.Wait();//blocks until CallNewAsyncMethod completes
person Travis J    schedule 13.08.2015