Search code examples
c#wcfasync-awaitcallcontext

Using the CallContext to store the HttpContext for WCF


I currently have a WCF service used to perform some database queries and send a mail. Long story short, both methods are async use HttpContext.Current somewhere in their implementation.

My initial problem is that after the first await, HttpContext.Current becomes null and therefore, the second operation fails. I searched on Google for hours now and I tested everything I found... Custom synchronization context, the appSettings in the web.config, targeting .NET 4.5, enabling the ASP.NET compatibility, but nothing worked.

Then, I found this SO post talking about the CallContext. Basically, the idea is to store HttpContext.Current in the CallContext. I tested and yeepee, it worked. However, as I didn't know exactly what was the CallContext, I read about it.

I'm not sure I really understood everything correctly but after my reading, I have a concern. I might be wrong but it seems that there is no guarantee that the thread restored once the async call is done is the same than the initial thread. The issue is that I'm storing several values in the HttpContext and I'm afraid that the first method execute with user A values, then, once the async call is done, that the second method execute with user B values (as the HttpContext wouldn't be the same).

I guess people will be tempted to tell me to only store these values in the CallContext but I created a whole architecture before being confronted to the WCF issue, so I'd like not to review it entirely, which is why the CallContext comes handy as the changes are minor.

Can someone tell me whether my theory is correct or not?


Solution

  • WCF is somewhat whole SOA Architecture given to you out of box with multiple protocols support & everything is configurable besides also you can extension customize everything. So getting all is very tricky.Just basics:

    Three types of WCF concurrency are :

    Single: A single request has access to the WCF service object at a given moment of time.

    Multiple: In this scenario, multiple requests can be handled by the WCF service object at any given moment of time.

    Reentrant: A single request thread has access to the WCF service object, but the thread can exit the WCF service to call another WCF service or can also call a WCF client through callback and reenter without deadlock.

    Seems simple enough but wait it has instancing modes that are different from concurrency:

    - Per call A new InstanceContext (and therefore service object) is created for each client request.

    - Per session A new InstanceContext (and therefore service object) is created for each new client session and maintained for the lifetime of that session (this requires a binding that supports sessions).

    - Single instance: A single InstanceContext (and therefore service object) handles all client requests for the lifetime of the application.

    Default Instance Mode is Per session and Default Concurrency mode is single

    that means for WCF Service until you change your service has only one instance context, is allowed to have a maximum of one thread processing messages in the instance context at a time. Other threads wishing to use the same instance context must block until the original thread exits the instance context

    So what you fear seems not possible until you made code changes for that and want it to be happen.

    For more details refer : MSDN