Beberapa perpustakaan mungkin hanya menyediakan metode asinkron, tetapi ASP.net memang sinkron. Kali ini kami mengalami masalah: fungsi panggilan balik tidak akan dijalankan hingga halaman ditampilkan. Dan proses yang saya perlukan adalah: melakukan verifikasi pada fungsi callback sebelum halaman dapat dirender. Mutex dan AutoResetEvent menyediakan metode untuk mengoordinasikan langkah-langkah eksekusi thread melalui semaphore.
XmppClientConnection adalah kelas di perpustakaan agsxmppJabber. Memanggil Open akan segera kembali ke klien (yaitu) untuk merender halaman, terlepas dari apakah itu berhasil atau tidak. Pada saat yang sama, thread lain akan melakukan operasi login dan akun baru. Setelah berhasil, event callback akan terpicu, sehingga callback tersebut akan dieksekusi hanya setelah halaman dirender, yang tidak sesuai dengan logika yang kita inginkan. Kami menyebut thread yang memanggil Open: Jabber thread, dan thread yang melakukan login: thread tambahan dari thread Jabber.
Ide awal saya adalah menggunakan Monitor, kode:
objek pribadi objlock=objek baru();
public void RegisterJab(string nama pengguna, kata sandi string, server string)
{
_koneksi.Server = server;
_koneksi.Nama Pengguna = nama pengguna;
_koneksi.Kata Sandi = kata sandi;
_koneksi.Port = 80;
_koneksi.UseSSL = salah;
_koneksi.AutoResolveConnectServer = benar;
_koneksi.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_koneksi.UseStartTLS = benar;
_koneksi.RegisterAccount = benar;
Monitor.Enter(objlock);
_koneksi.Buka();
Monitor.Tunggu(objlock);
_koneksi.Tutup();
}
private void XmppCon_OnRegistered (pengirim objek)
{
IsSuccessfull = benar;
Monitor.Keluar(objlock);
}
Pengecualian akan muncul saat menjalankan Monitor.Exit(): SynchronizationLockException, karena thread bantu Jabber bukan pemilik kunci. Ditemukan bahwa Monitor seperti bagian kritis dan tidak cocok untuk menangani situasi ini.
Kemudian, dipindahkan ke Mutex, Mutex: adalah primitif sinkronisasi yang memberikan akses eksklusif ke sumber daya bersama hanya pada satu thread. Jika satu thread memperoleh mutex, thread kedua yang memperoleh mutex tersebut akan ditangguhkan hingga thread pertama melepaskan mutex tersebut.
Mutex sangat cocok untuk mewujudkan fungsi ini, tapi adakah cara yang lebih mudah? Itulah AutoResetEvent: memungkinkan thread untuk berkomunikasi satu sama lain dengan memberi sinyal. Biasanya, komunikasi ini melibatkan sumber daya yang memerlukan akses eksklusif ke thread tersebut. Yang paling penting adalah menyediakan metode komunikasi antar thread, sehingga langkah pemanggilan thread dapat dikontrol dengan lebih fleksibel. Yang kami gunakan adalah semaphore.
Kode:
Namespace LoginBase
{
Daftar kelas publik
{
XmppClientConnection_connection;
AutoResetEvent statis myResetEvent;
bool publik Digunakan;
Daftar Publik()
{
_koneksi = XmppClientConnection baru();
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_koneksi.OnLogin += ObjectHandler baru(XmppCon_OnLogin);
_koneksi.OnRegisterError += OnXmppErrorHandler baru(XmppCon_OnRegErr);
_koneksi.OnRegistered += ObjectHandler baru(XmppCon_OnRegistered)
;
bool publik IsSuccessfull = false;
public void RegisterJab(string nama pengguna, kata sandi string, server string)
{
_koneksi.Server = server;
_koneksi.Nama Pengguna = nama pengguna;
_koneksi.Kata Sandi = kata sandi;
_koneksi.Port = 80;
_koneksi.UseSSL = salah;
_koneksi.AutoResolveConnectServer = benar;
_koneksi.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_koneksi.UseStartTLS = benar;
_koneksi.RegisterAccount = benar;
myResetEvent = AutoResetEvent baru(salah);
_koneksi.Buka();
myResetEvent.WaitOne(20 * 1000, benar);
_koneksi.Tutup();
}
private void XmppCon_OnRegistered (pengirim objek)
{
IsSuccessfull = benar;
myResetEvent.Set();
}
private void XmppCon_OnLogin (pengirim objek)
{
IsSuccessfull = benar;
myResetEvent.Set();
}
private void XmppCon_OnRegErr(pengirim objek, Elemen e)
{
//Jika errCode adalah 409, pengguna sudah ada
IsSuccessfull = salah;
Elemen xn = e.SelectSingleElement("kesalahan");
if (xn.Atribut("kode") == "409")
Digunakan = benar;
myResetEvent.Set()
;
}
}
Pertama atur ke status non-terminated, lalu masuk ke thread Jabber, blokir thread Asp, dan tunggu. Jika peristiwa panggilan balik dipicu, status disetel ke dihentikan dan thread asp melanjutkan eksekusi.
Sinkronisasi berhasil diselesaikan, sehingga thread Asp tidak akan dilanjutkan hingga thread tambahan Jabber selesai dijalankan.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html