4
Vote

WorkContextAccessor shouldn't use ThreadStatic for work contexts created independent from an http context

description

If there is no http context present then WorkContextAccessor stores created work contexts in a thread-static dictionary. The issue with this implementation is that it relies on the same thread running a given execution path from start to finish (what is generally an issue in ASP.NET). This is certainly not the case however if the execution path contains async code since then the execution can start with one thread and (after resuming from an async call) continue with another one.

Instead WorkContextAccessor could use System.Runtime.Remoting.Messaging.CallContext to store the work contexts, similarly to how the Orchard.Environment.State.ContextState<T> object works. CallContext.LogicalSet/GetData() could work for this but it probably isn't practically possible since it would need the WorkContext to be immutable.

So I'm not sure how this can be solved. Probably WorkContextAccessor could enable the use of an external context object (apart from HttpContext) that is maintained by the caller, and thus can be carried in an arbitrary way? A hackish workaround available now is to explicitly set an http context through IHttpContextAccessor before creating the WC and then using that to carry the work contexts through layers.

Related: https://orchard.codeplex.com/workitem/20474

comments

Piedone wrote Mar 18 at 7:46 PM

One addition: if we enable the usage of an external "work context holder" other than HttpContext, then that should be used in background tasks in the outer work context scope creation.