Call asynchronous methods in Asp.net -- use semaphores

Source: Internet
Author: User

Time coupling: concurrency and Order (the relative position of an event in time, that is, the "Tower" must occur before the "Tower)
Some libraries may only provide asynchronous methods, while ASP.net is indeed synchronous. This time, a problem occurs: the callback function will be executed only after the page is displayed. The process I need is to perform verification in the callback function before the page can be displayed. Mutex and AutoResetEvent provide a method to coordinate the thread execution steps through semaphores.
XmppClientConnection is a class in the agsxmppJabber library. When Open is called, the client (ie) is immediately returned to present the page. no matter whether the page is successful or not, the client will log on to the other thread to create an account, the callback event is triggered after the page is displayed, which does not conform to our logic. We call the Open thread as the Jabber thread, and the thread for login execution as the auxiliary thread of the Jabber thread.

My initial thought was to use Moniter with 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 );
}

When Moniter. Exit () is executed, an exception will be thrown: SynchronizationLockException, because the Jabber auxiliary thread is not the lock owner. It is found that Moniter is like a critical section and is not suitable for handling this situation.
Later, to Mutex, Mutex is a synchronization primitive, which grants only one thread exclusive access to shared resources. If a thread obtains the mutex, the second thread to obtain the mutex will be suspended until the first thread releases the mutex.
Mutex is very suitable for the implementation of this function, but is there any easier way? That is, AutoResetEvent: allows threads to communicate with each other by sending signals. Generally, this communication involves resources that the thread needs to exclusively access. The most important thing is that it provides a method for inter-thread communication, so that we can more flexibly control the thread call steps, 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 (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 ();

}


}

}

It is set to a non-terminating State first, then enters the Jabber thread, blocks Asp threads, and waits. The timeout time is 20 seconds. If a callback event is triggered, the setting state is terminated, and the asp thread continues to execute.
The synchronization is completed successfully. In this way, the Asp thread will continue until the execution of the Jabber auxiliary thread is complete.
Note: RegisterAsyncTask can also implement similar functions. It seems that it has a strong relationship with an asynchronous page. using it to implement this class won't be universal. For more information, see Msdn.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.