In our WPF application users can log out and then log in into the system. With current implementation Csla.Xaml.ApplicationContextManager we sometime have interesting problem. I would like to check if anyone had the same problem before, or have any other comments. Here is the problem.
ApplicationContextManager stores IPrincipal internally, and the value is shared between threads. That creates the problem in the following sequence of events.
I see some ways to address it, but interested to know how others do this and why.
We are on 220.127.116.11
So you start an async "Logoff" method that calls the DataPortal?
My best suggestion would be to add/alter the callback method and make sure to set
ApplicationContext.User = UnAuthenticatedPrincipal,
in the callback.
Sometimes the User object is stored in each thread and the DataPortal is unaware of how the ApplicationContextManager handles this so I would be very hesitant to change this behavior in the framework.
Not exactly. The logoff is NOT an async operation. I can logoff immediately and reflect this in UI, which I do.
Theare are couple commands I call before the logging using BeginExecute method. And I use the fact that DataPortal BeginExecute actually grabs some infromation from application context before logoff is done. Examle: save some user settings, layouts, log statistics etc. Those are completely independent, and I don't really need or want to syncrhonize them.
I also don't want to wait for them to be executed to complete logging off in UI. We are working with remote app server (over internet), so it can take some time.
Your soultion is valid though, thank you for the response.
I hate to say it, but this is a "feature" :)
The User property is stored in a static field to overcome the sad fact that WPF makes it nearly impossible to change the principal once the app is running. They really did not think through an app scenario where the user logs on and off the app without closing the app between users...
The BackgroundWorker copies the main thread's context into the background thread because in non-WPF scenarios that is the only way to get the context and principal to flow automatically onto the background thread.
I suppose it could be argued that the BackgroundWorker shouldn't copy the User property in a WPF app because the value is already universal. However, even that change wouldn't fix your problem, it would just trade one race condition for another...
Thank you Rocky. Can you elaborate what did you mean by " WPF makes it nearly impossible to change the principal once the app is running"?
Assuming I figure out how to workaround problem with async calls, do you envision more problems with changing principal?
Copyright (c) Marimer LLC