일부 라이브러리는 비동기 메서드만 제공할 수 있지만 ASP.net은 실제로 동기식입니다. 이번에는 페이지가 표시될 때까지 콜백 함수가 실행되지 않는다는 문제가 발생했습니다. 그리고 필요한 프로세스는 페이지가 렌더링되기 전에 콜백 함수에서 확인을 수행하는 것입니다. Mutex 및 AutoResetEvent는 세마포어를 통해 스레드 실행 단계를 조정하는 메서드를 제공합니다.
XmppClientConnection은 agsxmppJabber 라이브러리의 클래스입니다. Open을 호출하면 성공 여부에 관계없이 페이지를 렌더링하기 위해 즉시 다른 스레드가 로그인 및 새 계정 작업을 수행합니다. 성공하면 콜백 이벤트가 발생하므로 페이지가 렌더링된 후에만 콜백이 실행되므로 원하는 로직에 맞지 않습니다. Open을 호출하는 스레드인 Jabber 스레드와 로그인을 수행하는 스레드인 Jabber 스레드의 보조 스레드를 호출합니다.
내 초기 아이디어는 Monitor를 사용하는 것이었습니다. 코드는 다음과 같습니다.
개인 개체 objlock=새 개체();
공개 무효 RegisterJab(문자열 사용자 이름, 문자열 비밀번호, 문자열 서버)
{
_connection.Server = 서버;
_connection.Username = 사용자 이름;
_connection.Password = 비밀번호;
_connection.Port = 80;
_connection.UseSSL = 거짓;
_connection.AutoResolveConnectServer = true;
_connection.ConnectServer = null;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = true;
_connection.RegisterAccount = true;
모니터.Enter(objlock);
_connection.Open();
Moniter.Wait(objlock);
_connection.Close()
}
개인 무효 XmppCon_OnRegistered(개체 보낸 사람)
{
IsSuccessfull = 사실;
Monitor.Exit(objlock);
}
Monitor.Exit()를 실행할 때 예외가 발생합니다. Jabber 보조 스레드가 잠금의 소유자가 아니기 때문에 Monitor는 임계 섹션과 같으며 이 상황을 처리하는 데 적합하지 않습니다.
나중에 Mutex로 이동한 Mutex: 공유 리소스에 대한 독점 액세스를 하나의 스레드에만 부여하는 동기화 기본 요소입니다. 한 스레드가 뮤텍스를 획득하면 뮤텍스를 획득하는 두 번째 스레드는 첫 번째 스레드가 뮤텍스를 해제할 때까지 일시 중지됩니다.
Mutex는 이 기능을 구현하는 데 매우 적합하지만 더 쉬운 방법이 있습니까? 이것이 AutoResetEvent입니다. 스레드가 신호를 통해 서로 통신할 수 있도록 하는 것입니다. 일반적으로 이 통신에는 스레드가 독점적으로 액세스해야 하는 리소스가 포함됩니다. 가장 중요한 것은 스레드 간의 통신 방법을 제공하여 스레드의 호출 단계를 보다 유연하게 제어할 수 있다는 것입니다. 우리가 사용하는 것은 세마포입니다.
암호:
네임스페이스 LoginBase
{
공개 수업 등록
{
XmppClientConnection_connection;
정적 AutoResetEvent myResetEvent;
공개 bool IsUsed;
공개등록()
{
_connection = 새로운 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)
}
공개 bool IsSuccessfull = false;
공개 무효 RegisterJab(문자열 사용자 이름, 문자열 비밀번호, 문자열 서버)
{
_connection.Server = 서버;
_connection.Username = 사용자 이름;
_connection.Password = 비밀번호;
_connection.Port = 80;
_connection.UseSSL = 거짓;
_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()
}
개인 무효 XmppCon_OnRegistered(개체 보낸 사람)
{
IsSuccessfull = 사실;
myResetEvent.Set();
}
개인 무효 XmppCon_OnLogin(객체 보낸 사람)
{
IsSuccessfull = 사실;
myResetEvent.Set();
}
private void XmppCon_OnRegErr(객체 송신자, 요소 e)
{
//errCode가 409이면 사용자가 이미 존재하는 것입니다.
IsSuccessfull = 거짓;
요소 xn = e.SelectSingleElement("error");
if (xn.Attribute("code") == "409")
IsUsed = 사실;
myResetEvent.Set()
}
}
}
먼저 종료되지 않은 상태로 설정한 다음 Jabber 스레드를 입력하고 Asp 스레드를 차단한 후 대기 시간은 20초입니다. 콜백 이벤트가 트리거되면 상태는 종료됨으로 설정되고 ASP 스레드는 계속 실행됩니다.
동기화가 성공적으로 완료되었으므로 Jabber 보조 스레드의 실행이 완료될 때까지 Asp 스레드가 계속되지 않습니다.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html