Csla.Xaml.ApplicationContextManager question

Csla.Xaml.ApplicationContextManager question

Old forum URL: forums.lhotka.net/forums/t/11679.aspx


maxal posted on Tuesday, November 06, 2012

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.

  1. User pressed "Log off" button
  2. From the main thread we call DataPortal.BeginExecute method to do something, which creates Backgroundworker, new thread does not starts instantaneously, may take few milliseconds.
  3. From the main thread we do something like this:  ApplicationContext.User = UnAuthenticatedPrincipal, which changes the value of stored principal in ApplicationContextManager
  4. Now the background worker's thread is finally started, and SetThreadContext method is called, which changes the value of ApplicationContext.User again.

I see some ways to address it, but interested to know how others do this and why.

We are on 4.3.10.0

JonnyBee replied on Tuesday, November 06, 2012

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.

maxal replied on Tuesday, November 06, 2012

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.

RockfordLhotka replied on Tuesday, November 06, 2012

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...

maxal replied on Wednesday, November 07, 2012

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