【dinghao】在Asp.net中呼叫非同步方法--使用訊號量
時間耦合:併發和次序(事件在時間中的相對位置,即“塔”必須在“嘀”之前發生)
有些庫可能只提供了非同步方法,而ASP.net確是同步的,這次就遇到一個問題:頁面顯示出來以後才會執行回撥函式。而我需要的流程是:在回撥函式中執行驗證,然後才能呈現頁面。Mutex,AutoResetEvent提供了通過訊號量來協調執行緒執行步驟的方法。
XmppClientConnection是agsxmppJabber庫中的類,呼叫Open會立即返回客戶端(ie)呈現該頁面,而不管是否成功,同時會在另一個執行緒會執行登陸,新建帳戶的操作,成功後會觸發回撥事件,這樣一來頁面呈現後才會執行回撥,不符合我們要的邏輯。我們把呼叫Open的執行緒叫做:Jabber執行緒,把執行登陸的執行緒叫做:Jabber執行緒的輔助執行緒。
有些庫可能只提供了非同步方法,而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);
}
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();
}
}
}
{
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執行緒才會繼續下去。
注:RegisterAsyncTask,也可以實現類似功能。好像它和非同步頁有很強的關聯,用它實現這個類就沒有了通用性。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-332342/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【dinghao】asp.net2.0中非同步呼叫WebService(非同步頁)ASP.NET非同步Web
- asp.net 應用程式中同步方法呼叫非同步方法無響應解決方法ASP.NET非同步
- 視訊課程-迴圈中呼叫非同步方法非同步
- windows多執行緒同步--訊號量Windows執行緒
- ASP.NET AJAX中的非同步PageMethod呼叫ASP.NET非同步
- 使用訊號量進行同步的共享記憶體機制記憶體
- 執行緒同步(windows平臺):訊號量執行緒Windows
- iOS多執行緒非同步訊號量iOS執行緒非同步
- 【dinghao】在.net程式中使用資源
- ASP.NET AJAX中的非同步Web Services呼叫ASP.NET非同步Web
- 唯快不破:【多執行緒】使用訊號量進行同步執行緒
- system -v 訊號量的使用
- 無名訊號量實現相關程式同步
- uc/os-iii學習筆記-資源管理(中斷、訊號、訊號量、互斥訊號量)筆記
- 在Java中呼叫Groovy方法的又一種方法:使用介面Java
- Spring 3中非同步方法呼叫Spring非同步
- Linux程式間通訊——使用訊號量Linux
- 多個網路請求中GCD訊號量的使用GC
- 訊號課組(一) 訊號與系統 Part 0 MATLAB在訊號與系統中的使用Matlab
- Java 非同步呼叫方法Java非同步
- Linux中訊號量的實現Linux
- Linux中的System V訊號量Linux
- POSIX 訊號量
- 用訊號量解決程式的同步與互斥探討
- 程式間通訊——POSIX 有名訊號量與無名訊號量
- 【王巨集喜】在ASP.net中網站訪問量統計方法ASP.NET網站
- 在 docker 容器中捕獲訊號Docker
- 在 iOS 中實現方法鏈呼叫iOS
- 在CMakeLists.txt中設定版本號,並在程式碼中呼叫
- Java多執行緒—執行緒同步(單訊號量互斥)Java執行緒
- go中semaphore(訊號量)原始碼解讀Go原始碼
- liteos訊號量(八)
- django的訊號量Django
- Python 訊號量Python
- 同步和非同步關注的是訊息通訊機制,阻塞和非阻塞關注的是程式在等待呼叫結果(訊息,返回值)時的狀態非同步
- 在asp.net handler 中 使用 sessionASP.NETSession
- 在shell中捕捉訊號的命令(轉)
- 在python中定義[]呼叫的方法Python