Replies: 4 comments 23 replies
-
Hi, I've not used the Local/Client/*Context stuff but here are my thought on this:
In my opinion, since you are using the parallel you are responsible for making the stuff thread safe. Don't know what CSLA could provide here? It does not know if it's used in a parallel context or not. Futhermore you are resolving a new application context from the original DI scope which means - from a ApplicationContext perspective - you are still within one execution flow. So of course the "inner state" of the application context is preserved. |
Beta Was this translation helpful? Give feedback.
-
@mirecg see the notes in #4015 regarding how it will now be possible (not required) for code to safely use the local/client context collections. I'm sure all existing code uses the not-thread-safe methods and iterators - but that is "your" code, not CSLA code. Other than, as @Bowman74 notes, MobileFormatter. I am not concerned about MobileFormatter, because if someone is interacting with the object graph while it is being serialized they are already in such deep trouble as to where this won't matter. Generally speaking it is important to understand that CSLA and CSLA-based domain objects are not thread safe. Like the vast majority of the BCL, there's no thread safety implied except where specifically documented. |
Beta Was this translation helpful? Give feedback.
-
I'm using it as an general context storage of values/objects which are available to anyone down in the call hiearchy and isolated between threads. With LocalContext stored as |
Beta Was this translation helpful? Give feedback.
-
@mirecg Having said that, I'd be very careful with your assumption that having the context managers stored in TLS made them thread safe. That is very much not true. Outside of the obvious observation that it doesn't support threads interacting with the same storage at all, multiple current interrupting and even asynchronous operations using things like IO completion ports can all be executed on the same thread. |
Beta Was this translation helpful? Give feedback.
-
Hello, I'm migrating from Csla4 to Csla8. A big jump, I know.
But what's the question or maybe an issue I have?
ApplicationContext.LocalContext is provided by default IContextManager implementation which is ApplicationContextManager.
ApplicationContextManager uses AsyncLocal storage for both LocalContext and ClientContext.
In Csla4 the LocalContext was stored in TLS and is still supported in Csla8 by ApplicationContextManagerTls implementation.
So far so good.
For new applications with an async/await programming style, TLS storage is not working anymore, when we want to share context between async calls.
AsyncLocal enables to "flow" data from one task to another. So when we set something in appContext.LocalContext (appContext is ApplicationContext resolved from IServiceProvider) and make some async/await call or Task.Run(), we will get the same instance of LocalContext in invoked async calls/tasks.
The problem I see, is that the LocalContext is the value stored in AsyncLocal as a whole, so that when we initialize it in one task and invoke from there another async/await call, that call will "see" the same instance of LocalContext with the same values in it.
When we perform same parallel work the invoked task well run over the same instance of LocalContext with potential conncurrency problems.
See this code example with comments in it, which describes the problem better.
I would assume that the LocalContext is implemented as
ConcurrentDictionary<string, AsyncLocal<object>>
which would behave more like synchronous style programming, e.g. invoking only sync calls, which shared the context in the call hiearchy:Beta Was this translation helpful? Give feedback.
All reactions