Some libraries may only provide asynchronous methods, but ASP.net is indeed synchronous. This time we encountered a problem: the callback function will not be executed until the page is displayed. And the process I need is: perform verification in the callback function before the page can be rendered. Mutex and AutoResetEvent provide methods to coordinate thread execution steps through semaphores.
XmppClientConnection is a class in the agsxmppJabber library. Calling Open will immediately return to the client (ie) to render the page, regardless of whether it is successful or not. At the same time, another thread will perform the login and new account operations. After success, the callback event will be triggered, so The callback will be executed only after the page is rendered, which does not conform to the logic we want. We call the thread that calls Open: Jabber thread, and the thread that performs login: the auxiliary thread of Jabber thread.
My initial idea was to use Monitor, code:
private object objlock=new object();
public void RegisterJab(string username, string password, string server)
{
_connection.Server = server;
_connection.Username = username;
_connection.Password = password;
_connection.Port = 80;
_connection.UseSSL = false;
_connection.AutoResolveConnectServer = true;
_connection.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = true;
_connection.RegisterAccount = true;
Moniter.Enter(objlock);
_connection.Open();
Moniter.Wait(objlock);
_connection.Close();
}
private void XmppCon_OnRegistered(object sender)
{
IsSuccessfull = true;
Moniter.Exit(objlock);
}
An exception will be thrown when executing Monitor.Exit(): SynchronizationLockException, because the Jabber auxiliary thread is not the owner of the lock. It is found that Monitor is like a critical section and is not suitable for handling this situation.
Later, moved to Mutex, Mutex: is a synchronization primitive that grants exclusive access to a shared resource to only one thread. If one thread acquires a mutex, the second thread to acquire the mutex will be suspended until the first thread releases the mutex.
Mutex is very suitable for realizing this function, but is there an easier way? That's AutoResetEvent: allowing threads to communicate with each other by signaling. Typically, this communication involves resources to which the thread needs exclusive access. The most important thing is that it provides a method of communication between threads, so that the calling steps of the thread can be controlled more flexibly. What we use is a semaphore.
Code:
namespace LoginBase
{
public class Register
{
XmppClientConnection_connection;
static AutoResetEvent myResetEvent;
public bool IsUsed;
publicRegister()
{
_connection = new XmppClientConnection();
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.OnLogin += new ObjectHandler(XmppCon_OnLogin);
_connection.OnRegisterError += new OnXmppErrorHandler(XmppCon_OnRegErr);
_connection.OnRegistered += new ObjectHandler(XmppCon_OnRegistered);
}
public bool IsSuccessfull = false;
public void RegisterJab(string username, string password, string server)
{
_connection.Server = server;
_connection.Username = username;
_connection.Password = password;
_connection.Port = 80;
_connection.UseSSL = false;
_connection.AutoResolveConnectServer = true;
_connection.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = true;
_connection.RegisterAccount = true;
myResetEvent = new AutoResetEvent(false);
_connection.Open();
myResetEvent.WaitOne(20 * 1000, true);
_connection.Close();
}
private void XmppCon_OnRegistered(object sender)
{
IsSuccessfull = true;
myResetEvent.Set();
}
private void XmppCon_OnLogin(object sender)
{
IsSuccessfull = true;
myResetEvent.Set();
}
private void XmppCon_OnRegErr(object sender, Element e)
{
//If errCode is 409, the user already exists
IsSuccessfull = false;
Element xn = e.SelectSingleElement("error");
if (xn.Attribute("code") == "409")
IsUsed = true;
myResetEvent.Set();
}
}
}
First set it to a non-terminated state, then enter the Jabber thread, block the Asp thread, and wait. The timeout is 20 seconds. If the callback event is triggered, the status is set to terminated and the asp thread continues execution.
The synchronization is completed successfully, so that the Asp thread will not continue until the Jabber auxiliary thread has finished executing.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html