when CurrentPrincipal is set in async call back, NET 2.0 loses CurrentPrincipal

K

kochobay

i use a form to login the system.
After database checks System.Threading.Thread.CurrentPrincipal is being
set in async call back.
During database chekcs, user interface displays a progress bar. And
this works fine with .NET 1.1.
But i newly ported application to NET 2.0 (Visual Studio 2005) and
after async call back, System.Threading.Thread.CurrentPrincipal is
resetting to empty GenericPrincipal.

I think it's a bug.

Any suggestion?
 
A

Andy

Not a bug; the Async is causing code to run on another thread. That's
the thread getting the principal object set. The thread which kicks
off the async operation never had its principal changed.

Andy
 
K

kochobay

Thanks for reply Andy,

But there exists something strange.
I have a custom Principal class implement IPrincipal interface.
i have two delegate ike below

protected delegate object AsynchronousCall(params object[] args);
protected delegate void AsynchronousCallEnd(object arg);

and my background thread method is

IPrincipal Logon(string username, string password)
{
Principal myPrincipal = new Principal();
//Some login operations and populate myPrincipal.
return myPrincipal;
}

and i call this Logon method on button click
private void okButton_Click(object sender, System.EventArgs e)
{
AsynchronousCall asyncCall = new AsynchronousCall(Logon);
asyncCall.BeginInvoke(new object[] {uname.pwd}, new
AsyncCallback(OnLogonEnd), asyncCall);
}

and when my background thread finished its work , OnLogonEnd method
called back.

protected void OnLogonEnd(IAsyncResult ar)
{
AsynchronousCall d = (AsynchronousCall)ar.AsyncState;
object returnValue = d.EndInvoke(ar);
this.OnAsynchronousCallEnd(new object[] {returnValue});
this.Invoke(new AsynchronousCallEnd(this.OnAsynchronousCallEnd),
returnValue);
}

protected override void OnAsynchronousCallEnd(object arg)
{
System.Threading.Thread.CurrentPrincipal = (IPrincipal) arg;
new XForm().Show();
}

i debugged many times and when code entered XForm OnLoad method
System.Threading.Thread.CurrentPrincipal has correct value.

private void XForm_Load(object sender, System.EventArgs e)
{
System.Security.Principal.IPrincipal p =
System.Threading.Thread.CurrentPrincipal;
MessageBox.Show(p.Identity.Name);
} // has correct value


But i click on the XForm, i saw the incorrect GenericPrincipal in the
CurrentPrincipal.

private void XForm_Click(object sender, System.EventArgs e)
{
System.Security.Principal.IPrincipal p =
System.Threading.Thread.CurrentPrincipal;
MessageBox.Show(p.Identity.Name);
} // has INCORRECT value

Thanks a lof for your interest, again.
 
K

kochobay

when i write method OnLogonEnd here , i made mistake sorry.

it is like this;

protected void OnLogonEnd(IAsyncResult ar)
{
AsynchronousCall d = (AsynchronousCall)ar.AsyncState;
object returnValue = d.EndInvoke(ar);
this.Invoke(new AsynchronousCallEnd(this.OnAsynchronousCallEnd),
returnValue);
}
 
K

kochobay

I found a solution , I think...

When ok button clicked ,
i called login and synchronization process (that takes long time) and i
did not want to freeze my main form, and wanted to display some
information about the process.
For this reason i called login and synchronization process on another
THREAD. In this background thread, i pumped several messages back to
the main form. For this pupose i used Form.Invoke() method for thread
safety. And when the background thread finished its work, i set a
Principal to System.Threading.Thread.CurrentPrincipal.

I use an architecture same as indicated at link below .
http://www.devx.com/codemag/Article/20639/0/page/3

And It was good in .NET 1.1 framework.

When i ported to NET 2.0, after background process completed , i
haven't seen the principal that i put into
System.Threading.Thread.CurrentPrincipal. It was lost.

Long time i drove crazy...

At last i found a workaround.
First, in callback method i set my principal as default principal
protected void OnLogonEnd(IAsyncResult ar)
{
....
AppDomain.CurrentDomain.SetThreadPrincipal(myPrincipal);
}

Second, after invocation of the background thread as mentioned previous
post

AsynchronousCall asyncCall = new AsynchronousCall(Logon);
asyncCall.BeginInvoke(new object[] {uname.pwd}, new
AsyncCallback(OnLogonEnd), asyncCall);

i added the followwing code

if
(!System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated)
System.Threading.Thread.CurrentPrincipal = null;

This is bug or not. I do not know.
Only thing that i know is that there exists a tedious difference on
threading and operating on CurrentPrincipal between 1.1 and 2.0...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top