Some libraries may provide only asynchronous methods, and ASP.net is indeed synchronized, and this time there is a problem: the page will not perform the callback function until it is displayed. The process I need is to perform validation in the callback function before the page can be rendered. Mutex,autoresetevent provides a way to coordinate thread execution steps by semaphores.
Xmppclientconnection is a class in the Agsxmppjabber library, calling open immediately returns the client (IE) to render the page, regardless of whether it succeeds, while another thread will execute the login, create a new account, and then trigger the callback event when it succeeds. This will not execute the callback until the page is rendered, which does not correspond to the logic we want. We call open the thread called: Jabber thread, the execution of the landing thread is called: Jabber thread of the worker thread.
My initial idea was to use Moniter, the 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 is thrown when executing moniter.exit (): SynchronizationLockException, because the Jabber worker thread is not the owner of the lock. found that the moniter is very much like a critical area and does not handle this case.
Later, it went to Mutex,mutex: A synchronization primitive that granted exclusive access to a shared resource to only one thread. If a thread acquires a mutex, the second thread to obtain the mutex is suspended until the first thread releases the mutex.
A mutex is a good fit for this feature, but is there a simpler way to do it? That's AutoResetEvent: Allow threads to communicate with each other by sending signals. Typically, this communication involves resources that the thread requires exclusive access to. The most important thing is that he provides a way to communicate between threads, so that you can more flexibly control the call steps of the thread, we use the semaphore.
Code:
namespace Loginbase
{
public class Register
{
xmppclientconnection _connection;
static AutoResetEvent myresetevent;
public bool isused;
public Register ()
{
_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 (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)
{
//errcode If it is 409 there is already a user
issuccessfull = false;
Element xn = e.selectsingleelement ("error");
if (xn. Attribute ("code") = = "409")
isused = true;
Myresetevent.set ();
}
}
}
Set to a non-signaled state, then enter the Jabber thread, block the ASP thread, and wait for a timeout of 20 seconds. If a callback event is triggered, the setting state is terminated and the ASP thread continues to execute.
Synchronization completes successfully, so that the ASP thread will not continue until the Jabber worker thread has finished executing.