This project is read-only.

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


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.



Piedone wrote Mar 18, 2014 at 8: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.

Piedone wrote Sep 18, 2014 at 8:36 PM

This is possible to solve by wrapping background task Sweep()s into separate Autofac lifetime scopes where they each get a new IHttpContextAccessor implementation (IHttpContextAccessor by default is an application-wide singleton) with a fake HttpContext. This way the work context can be stored through IHttpContextAccessor in this fake, externally controlled HttpContext.

For a sample see Run() in Orchard Application Host: