I ran into a problem (bug?) HttpContext.Current you mentioned where HttpContext.Current not being transmitted with async code in a WCF service hosted in IIS, even with aspNetCompatiblity enabled and required.
I got my project using LogicalCallContext with CallContext.LogicalSetData and CallContext.LogicalGetData as described by Stephen Cleary in this blog post . I think setting up / getting your business context will work very well in your case and may be lighter weight and conceptually simpler than the SynchronizationContext custom. In your case, you still need to set up your business context ... maybe also set it to a LogicalCallContext , and I believe that everything will be fine.
I will explain my personal “solution” in more detail, although I admit that this is a bit of a hack since I manually flow the entire HttpContext object (and only to WCF methods). But then again, your case with your custom context object seems to be better suited.
In the ASP.NET web application I inherited, there were calls to HttpContext.Current throughout the business logic (not perfect). Obviously, the project worked fine until I wanted some of the WCF methods in the application to be async .
Many of the business logic challenges will involve loading ASP.NET pages, etc., where everything works fine as it is.
I solved (kludged?) My problem in .NET 4.5 by creating a small helper class ContextHelper and replacing all calls with HttpContext.Current with ContextHelper.CurrentHttpContext .
public class ContextHelper { public static void PrepareHttpContextFlow() { CallContext.LogicalSetData("CurrentHttpContext", HttpContext.Current); } public static HttpContext CurrentHttpContext { get { return HttpContext.Current ?? CallContext.LogicalGetData("CurrentHttpContext") as HttpContext; } } }
Now anytime that HttpContext.Current defined, my helper method essentially fails.
To make this work, the entry points for my WCF calls must call the PrepareHttpContextFlow method before the first await call, which is admittedly problematic, and the main reason I consider this to be kludge.
In my case, this drawback is mitigated by the fact that I have some OTHER manual calls necessary to add logical stack information for the added error logging context, which is lost when using async (since the physical stack information in the exception is not very useful for error logs in in this case). Therefore, at least if I do not forget to make one of the “prepare for asynchronous” calls, I must remember another :)