3

We've upgraded our code base to use async/await, but many previously working methods now crash as a result of the new asynchronous code (HttpContext = null being a common issue). I'm not sure how to get around this IComparer.Compare() method. Any ideas? Seems I cannot use async Task on the Compare method:

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;
}

If I cannot get around making this .NET IComparer.Compare() method async, are there any other alternatives (such as LINQ) I could use to sort my classes? One thing to note, I've simplified the above code, but there's really a lot going on in there and our sorting code is not trivial. There are about 10 different kinds of sorts we could use and each sort is really a three level sort (sort by a, then b, then c).

Thanks for your help!

VanAlan
  • 65
  • 6

2 Answers2

4

many previously working methods now crash as a result of the new asynchronous code (HttpContext = null being a common issue).

await will properly preserve HttpContext by default, so I find that issue odd. Please ensure you are running on .NET 4.5 and also targeting ASP.NET 4.5 in your web.config (by default, upgraded projects will target ASP.NET 4.0, which is incompatible with await).

I'm not sure how to get around this IComparer.Compare() method.

This is the first time I've ever heard of anyone doing an asynchronous comparison. What an... "interesting"... idea.

I'd recommend that you not perform I/O or remote service calls when comparing two in-memory objects. If you need to do I/O, then do it before the comparisons. You can store the I/O results either in the objects, in a dictionary mapping from objects to comparison values, or as ephemerons. Then your Compare method works entirely in-memory and can be synchronous.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • RE: HttpContext I'm in the process of refactoring the code and I believe that part is due because my code is not "async all the way" yet, for that particular call chain. However, what I find odd is that the WebForms website is unaffected by the new async code, but the MVC mobile website I'm working on just stays stuck, using the same code. – VanAlan Aug 14 '15 at 19:29
  • RE: IComparer.Compare() Maybe my code sample could be better. What I'm trying to represent is that the old compare function now has to deal with an async operation that was recently introduced further down the call stack. I agree, this should probably be refactored beyond just redefining my methods as async await. :) – VanAlan Aug 14 '15 at 19:30
0

You can make the method synchronous, but if you have to do this on a large scale it may become cumbersome. Use .Wait() after the assignment of the variable to ensure that the value is populated before moving on. It will not require your compare method to be marked as async.

var xx = x.CallNewAsyncMethod();
xx.Wait();//blocks until CallNewAsyncMethod completes
Travis J
  • 81,153
  • 41
  • 202
  • 273