Es posible que algunas bibliotecas solo proporcionen métodos asincrónicos, pero ASP.net es síncrono. Esta vez encontramos un problema: la función de devolución de llamada no se ejecutará hasta que se muestre la página. Y el proceso que necesito es: realizar la verificación en la función de devolución de llamada antes de que se pueda representar la página. Mutex y AutoResetEvent proporcionan métodos para coordinar los pasos de ejecución del hilo a través de semáforos.
XmppClientConnection es una clase en la biblioteca agsxmppJabber. Llamar a Open regresará inmediatamente al cliente (es decir) para representar la página, independientemente de si tiene éxito o no. Al mismo tiempo, otro hilo realizará las operaciones de inicio de sesión y nueva cuenta. Después del éxito, se activará el evento de devolución de llamada, por lo que la devolución de llamada se ejecutará solo después de que se represente la página, lo que no se ajusta a la lógica que queremos. Llamamos al hilo que llama a Abrir: hilo Jabber, y al hilo que realiza el inicio de sesión: el hilo auxiliar del hilo Jabber.
Mi idea inicial era utilizar Monitor, código:
objeto privado objlock=nuevo objeto();
public void RegisterJab (nombre de usuario de cadena, contraseña de cadena, servidor de cadena)
{
_conexión.Servidor = servidor;
_conexión.Nombre de usuario = nombre de usuario;
_conexión.Contraseña = contraseña;
_conexión.Puerto = 80;
_conexión.UseSSL = falso;
_connection.AutoResolveConnectServer = verdadero;
_connection.ConnectServer = nulo;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = verdadero;
_connection.RegisterAccount = verdadero;
Monitor.Enter(objlock);
_conexión.Open();
Monitorear.Esperar(objlock);
_conexión.Cerrar();
}
vacío privado XmppCon_OnRegistered (remitente del objeto)
{
Es exitoso = verdadero;
Monitor.Salir(objlock);
}
Se generará una excepción al ejecutar Monitor.Exit (): SynchronizationLockException, porque el subproceso auxiliar de Jabber no es el propietario del bloqueo. Se descubre que Monitor es como una sección crítica y no es adecuado para manejar esta situación.
Posteriormente, trasladado a Mutex, Mutex: es una primitiva de sincronización que otorga acceso exclusivo a un recurso compartido a un solo subproceso. Si un subproceso adquiere un mutex, el segundo subproceso que adquiera el mutex se suspenderá hasta que el primer subproceso libere el mutex.
Mutex es muy adecuado para realizar esta función, pero ¿existe una manera más sencilla? Eso es AutoResetEvent: permitir que los subprocesos se comuniquen entre sí mediante señales. Normalmente, esta comunicación implica recursos a los que el hilo necesita acceso exclusivo. Lo más importante es que proporciona un método de comunicación entre subprocesos, de modo que los pasos de llamada del subproceso se puedan controlar de manera más flexible. Lo que utilizamos es un semáforo.
Código:
espacio de nombres LoginBase
{
registro de clase pública
{
XmppClientConnection_conexión;
AutoResetEvent estático myResetEvent;
bool público se utiliza;
registro público()
{
_conexión = nueva XmppClientConnection();
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.OnLogin += nuevo ObjectHandler(XmppCon_OnLogin);
_connection.OnRegisterError += nuevo OnXmppErrorHandler(XmppCon_OnRegErr);
_connection.OnRegistered += nuevo ObjectHandler(XmppCon_OnRegistered)
;
bool público IsSuccessfull = falso;
public void RegisterJab (nombre de usuario de cadena, contraseña de cadena, servidor de cadena)
{
_conexión.Servidor = servidor;
_conexión.Nombre de usuario = nombre de usuario;
_conexión.Contraseña = contraseña;
_conexión.Puerto = 80;
_conexión.UseSSL = falso;
_connection.AutoResolveConnectServer = verdadero;
_connection.ConnectServer = nulo;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = verdadero;
_connection.RegisterAccount = verdadero;
myResetEvent = nuevo AutoResetEvent(false);
_conexión.Open();
myResetEvent.WaitOne(20 * 1000, verdadero);
_conexión.Cerrar();
}
vacío privado XmppCon_OnRegistered (remitente del objeto)
{
Es exitoso = verdadero;
myResetEvent.Set();
}
privado vacío XmppCon_OnLogin (remitente del objeto)
{
Es exitoso = verdadero;
myResetEvent.Set();
}
vacío privado XmppCon_OnRegErr (remitente del objeto, elemento e)
{
//Si errCode es 409, el usuario ya existe
Es exitoso = falso;
Elemento xn = e.SelectSingleElement("error");
si (xn.Attribute("código") == "409")
Se utiliza = verdadero;
miResetEvent.Set()
;
}
}
Primero configúrelo en un estado no terminado, luego ingrese al subproceso Jabber, bloquee el subproceso Asp y espere 20 segundos. Si se activa el evento de devolución de llamada, el estado se establece en terminado y el subproceso asp continúa la ejecución.
La sincronización se completa con éxito, por lo que el subproceso Asp no continuará hasta que el subproceso auxiliar Jabber haya terminado de ejecutarse.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html