ไลบรารีบางแห่งอาจจัดเตรียมวิธีการแบบอะซิงโครนัสเท่านั้น แต่ ASP.net เป็นแบบซิงโครนัสจริงๆ คราวนี้เราพบปัญหา: ฟังก์ชันการโทรกลับจะไม่ถูกดำเนินการจนกว่าเพจจะปรากฏขึ้น และกระบวนการที่ฉันต้องการคือ: ทำการตรวจสอบในฟังก์ชันโทรกลับก่อนจึงจะสามารถแสดงผลเพจได้ Mutex และ AutoResetEvent จัดเตรียมวิธีการประสานขั้นตอนการประมวลผลเธรดผ่านเซมาฟอร์
XmppClientConnection เป็นคลาสในไลบรารี agsxmppJabber การเรียกใช้ Open จะส่งคืนไปยังไคลเอ็นต์ทันที (เช่น) เพื่อแสดงผลเพจ โดยไม่คำนึงว่าจะสำเร็จหรือไม่ ในเวลาเดียวกัน เธรดอื่นจะดำเนินการล็อกอินและดำเนินการบัญชีใหม่ หลังจากสำเร็จ เหตุการณ์การโทรกลับจะถูกทริกเกอร์ ดังนั้นการโทรกลับจะดำเนินการหลังจากแสดงผลเพจแล้วเท่านั้น ซึ่งไม่สอดคล้องกับตรรกะที่เราต้องการ เราเรียกเธรดที่เรียก Open: Jabber thread และเธรดที่ทำการเข้าสู่ระบบ: เธรดเสริมของเธรด Jabber
ความคิดเริ่มแรกของฉันคือการใช้ Monitor รหัส:
วัตถุส่วนตัว objlock = วัตถุใหม่ ();
โมฆะสาธารณะ RegisterJab (ชื่อผู้ใช้สตริง, รหัสผ่านสตริง, เซิร์ฟเวอร์สตริง)
{
_connection.Server = เซิร์ฟเวอร์;
_connection.Username = ชื่อผู้ใช้;
_connection.Password = รหัสผ่าน;
_การเชื่อมต่อพอร์ต = 80;
_connection.UseSSL = เท็จ;
_connection.AutoResolveConnectServer = จริง;
_connection.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = จริง;
_connection.RegisterAccount = จริง;
Moniter.Enter(objlock);
_connection.เปิด();
Moniter รอ (objlock);
_connection.ปิด();
}
โมฆะส่วนตัว XmppCon_OnRegistered (ผู้ส่งวัตถุ)
-
IsSuccessfull = จริง;
Moniter.Exit (objlock);
-
ข้อยกเว้นจะเกิดขึ้นเมื่อดำเนินการ Monitor.Exit(): SynchronizationLockException เนื่องจากเธรดเสริมของ Jabber ไม่ใช่เจ้าของการล็อค พบว่า Monitor เป็นเหมือนส่วนสำคัญและไม่เหมาะสำหรับการจัดการสถานการณ์นี้
ต่อมาเมื่อย้ายไปที่ Mutex Mutex: เป็นการซิงโครไนซ์แบบดั้งเดิมที่ให้สิทธิ์การเข้าถึงทรัพยากรที่ใช้ร่วมกันเฉพาะกับเธรดเดียวเท่านั้น หากเธรดหนึ่งได้รับ mutex เธรดที่สองเพื่อรับ mutex จะถูกระงับจนกว่าเธรดแรกจะปล่อย mutex
Mutex เหมาะมากในการใช้ฟังก์ชั่นนี้ แต่มีวิธีที่ง่ายกว่านี้ไหม? นั่นคือ AutoResetEvent: อนุญาตให้เธรดสื่อสารระหว่างกันโดยการส่งสัญญาณ โดยทั่วไปแล้ว การสื่อสารนี้เกี่ยวข้องกับทรัพยากรที่เธรดต้องการการเข้าถึงแบบเอกสิทธิ์เฉพาะบุคคล สิ่งที่สำคัญที่สุดคือให้วิธีการสื่อสารระหว่างเธรด เพื่อให้ขั้นตอนการเรียกของเธรดสามารถควบคุมได้อย่างยืดหยุ่นมากขึ้น สิ่งที่เราใช้คือเซมาฟอร์
รหัส:
เนมสเปซ LoginBase
-
ลงทะเบียนชั้นเรียนสาธารณะ
-
XmppClientConnection_connection;
AutoResetEvent แบบคงที่ myResetEvent;
บูลสาธารณะ IsUsed;
ลงทะเบียนสาธารณะ()
{
_connection = XmppClientConnection ใหม่();
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.OnLogin += ObjectHandler ใหม่ (XmppCon_OnLogin);
_connection.OnRegisterError += OnXmppErrorHandler ใหม่ (XmppCon_OnRegErr);
_connection.OnRegistered += ObjectHandler ใหม่ (XmppCon_OnRegistered);
}
บูลสาธารณะ IsSuccessfull = false;
โมฆะสาธารณะ RegisterJab (ชื่อผู้ใช้สตริง, รหัสผ่านสตริง, เซิร์ฟเวอร์สตริง)
{
_connection.Server = เซิร์ฟเวอร์;
_connection.Username = ชื่อผู้ใช้;
_connection.Password = รหัสผ่าน;
_การเชื่อมต่อพอร์ต = 80;
_connection.UseSSL = เท็จ;
_connection.AutoResolveConnectServer = จริง;
_connection.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = จริง;
_connection.RegisterAccount = จริง;
myResetEvent = ใหม่ AutoResetEvent(false);
_connection.เปิด();
myResetEvent.WaitOne (20 * 1,000 จริง);
_connection.ปิด();
}
โมฆะส่วนตัว XmppCon_OnRegistered (ผู้ส่งวัตถุ)
-
IsSuccessfull = จริง;
myResetEvent.Set();
}
โมฆะส่วนตัว XmppCon_OnLogin (ผู้ส่งวัตถุ)
-
IsSuccessfull = จริง;
myResetEvent.Set();
-
โมฆะส่วนตัว XmppCon_OnRegErr (ผู้ส่งวัตถุ องค์ประกอบ e)
-
//หาก errCode เป็น 409 แสดงว่า มีผู้ใช้อยู่แล้ว
IsSuccessfull = เท็จ;
องค์ประกอบ xn = e.SelectSingleElement("ข้อผิดพลาด");
ถ้า (xn.Attribute("รหัส") == "409")
ใช้แล้ว = จริง;
myResetEvent.Set();
}
}
}
ขั้นแรกให้ตั้งค่าเป็นสถานะที่ไม่สิ้นสุด จากนั้นเข้าสู่เธรด Jabber บล็อกเธรด Asp และรอสักครู่ หากเหตุการณ์การเรียกกลับถูกทริกเกอร์ สถานะจะถูกตั้งค่าเป็นสิ้นสุด และเธรด asp ดำเนินการต่อไป
การซิงโครไนซ์เสร็จสมบูรณ์แล้ว ดังนั้นเธรด Asp จะไม่ดำเนินการต่อจนกว่าเธรดเสริม Jabber จะดำเนินการเสร็จสิ้น
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html