Certaines bibliothèques peuvent ne fournir que des méthodes asynchrones, mais ASP.net est bel et bien synchrone. Cette fois, nous avons rencontré un problème : la fonction de rappel ne sera exécutée que lorsque la page sera affichée. Et le processus dont j'ai besoin est le suivant : effectuer une vérification dans la fonction de rappel avant que la page puisse être rendue. Mutex et AutoResetEvent fournissent des méthodes pour coordonner les étapes d'exécution des threads via des sémaphores.
XmppClientConnection est une classe de la bibliothèque agsxmppJabber. L'appel d'Open reviendra immédiatement au client (c'est-à-dire) pour restituer la page, que cela réussisse ou non. En même temps, un autre thread effectuera les opérations de connexion et de nouveau compte. Après succès, l'événement de rappel sera déclenché, donc le rappel ne sera exécuté qu'après le rendu de la page, ce qui n'est pas conforme à la logique souhaitée. Nous appelons le thread qui appelle Open : thread Jabber, et le thread qui effectue la connexion : le thread auxiliaire du thread Jabber.
Mon idée initiale était d'utiliser Monitor, code :
objet privé objlock=nouvel objet();
public void RegisterJab (nom d'utilisateur de chaîne, mot de passe de chaîne, serveur de chaîne)
{
_connection.Server = serveur ;
_connection.Username = nom d'utilisateur ;
_connection.Password = mot de passe ;
_connexion.Port = 80 ;
_connection.UseSSL = faux ;
_connection.AutoResolveConnectServer = true ;
_connection.ConnectServer = null ;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = true ;
_connection.RegisterAccount = true ;
Moniter.Enter(objlock);
_connection.Open();
Surveiller.Wait(objlock);
_connection.Close();
}
private void XmppCon_OnRegistered (expéditeur de l'objet)
{
IsSuccessfull = vrai ;
Moniter.Exit(objlock);
}
Une exception sera levée lors de l'exécution de Monitor.Exit() : SynchronizationLockException, car le thread auxiliaire Jabber n'est pas le propriétaire du verrou. Il s'avère que Monitor est comme une section critique et n'est pas adapté pour gérer cette situation.
Plus tard, déplacé vers Mutex, Mutex : est une primitive de synchronisation qui accorde un accès exclusif à une ressource partagée à un seul thread. Si un thread acquiert un mutex, le deuxième thread qui acquiert le mutex sera suspendu jusqu'à ce que le premier thread libère le mutex.
Mutex est très approprié pour réaliser cette fonction, mais existe-t-il un moyen plus simple ? C'est AutoResetEvent : permettre aux threads de communiquer entre eux par signalisation. Généralement, cette communication implique des ressources auxquelles le thread a besoin d'un accès exclusif. Le plus important est qu'il fournit une méthode de communication entre les threads, afin que les étapes d'appel du thread puissent être contrôlées de manière plus flexible. Ce que nous utilisons est un sémaphore.
Code:
espace de noms LoginBase
{
classe publique
{
XmppClientConnection_connection ;
statique AutoResetEvent myResetEvent ;
public bool est utilisé ;
publicRegister()
{
_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 (nom d'utilisateur de chaîne, mot de passe de chaîne, serveur de chaîne)
{
_connection.Server = serveur ;
_connection.Username = nom d'utilisateur ;
_connection.Password = mot de passe ;
_connexion.Port = 80 ;
_connection.UseSSL = faux ;
_connection.AutoResolveConnectServer = true ;
_connection.ConnectServer = null ;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = true ;
_connection.RegisterAccount = true ;
monResetEvent = new AutoResetEvent(false);
_connection.Open();
myResetEvent.WaitOne(20 * 1000, vrai);
_connection.Close();
}
private void XmppCon_OnRegistered (expéditeur de l'objet)
{
IsSuccessfull = vrai ;
monResetEvent.Set();
}
private void XmppCon_OnLogin (expéditeur de l'objet)
{
IsSuccessfull = vrai ;
monResetEvent.Set();
}
private void XmppCon_OnRegErr (expéditeur d'objet, élément e)
{
//Si errCode est 409, l'utilisateur existe déjà
IsSuccessfull = faux ;
Élément xn = e.SelectSingleElement("erreur");
if (xn.Attribute("code") == "409")
EstUtilisé = vrai ;
monResetEvent.Set();
}
}
}
Définissez-le d'abord sur un état non terminé, puis entrez dans le thread Jabber, bloquez le thread Asp et attendez. Le délai d'attente est de 20 secondes. Si l'événement de rappel est déclenché, le statut est défini sur Terminé et le thread asp continue son exécution.
La synchronisation s'est terminée avec succès, de sorte que le thread Asp ne continuera pas tant que le thread auxiliaire Jabber n'aura pas fini de s'exécuter.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html