程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 在Asp.net中調用異步方法-使用信號量

在Asp.net中調用異步方法-使用信號量

編輯:關於ASP.NET

有些庫可能只提供了異步方法,而ASP.net確是同步的,這次就遇到一個問題:頁面顯示出來以後才會執行回調函數。而我需要的流程是:在回調函數中執行驗證,然後才能呈現頁面。Mutex,AutoResetEvent提供了通過信號量來協調線程執行步驟的方法。

XmppClientConnection是agsxmppJabber庫中的類,調用Open會立即返回客戶端(ie)呈現該頁面,而不管是否成功,同時會在另一個線程會執行登陸,新建帳戶的操作,成功後會觸發回調事件,這樣一來頁面呈現後才會執行回調,不符合我們要的邏輯。我們把調用Open的線程叫做:Jabber線程,把執行登陸的線程叫做:Jabber線程的輔助線程。

我最初的想法是使用Moniter,代碼:

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);
     }

在執行Moniter.Exit()時會拋出異常:SynchronizationLockException,因為Jabber輔助線程並不是鎖的擁有者.發現Moniter很像臨界區,並不適處理這種情況合。

後來,轉到了Mutex,Mutex: 是同步基元,它只向一個線程授予對共享資源的獨占訪問權。如果一個線程獲取了互斥體,則要獲取該互斥體的第二個線程將被掛起,直到第一個線程釋放該互斥體。

Mutex很合適這個功能的實現,可是還有沒有更簡便的方法呢?那就是AutoResetEvent:允許線程通過發信號互相通信。通常,此通信涉及線程需要獨占訪問的資源。最重要的是他提供了線程間通訊的方法,這樣可以更靈活的控制線程的調用步驟,我們用到的就是信號量。

代碼:

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)
     {
       //errCode如果是409則已經存在用戶
       IsSuccessfull = false;
       Element xn = e.SelectSingleElement("error");
       if (xn.Attribute("code") == "409")
         IsUsed = true;
       myResetEvent.Set();
     }
   }
}

先設置為非終止狀態,然後進入Jabber線程,阻塞Asp線程,並且等待,超時時間為20秒。如果觸發了回調事件,則設置狀態為終止,asp線程繼續執行。

成功完成同步,這樣一來,必須等到Jabber輔助線程執行完,Asp線程才會繼續下去。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved