Некоторые библиотеки могут предоставлять только асинхронные методы, но ASP.net действительно синхронен. На этот раз мы столкнулись с проблемой: функция обратного вызова не будет выполнена до тех пор, пока страница не будет отображена. И мне нужен следующий процесс: выполнить проверку в функции обратного вызова, прежде чем страница сможет быть отображена. Mutex и AutoResetEvent предоставляют методы для координации шагов выполнения потока через семафоры.
XmppClientConnection — это класс в библиотеке agsxmppJabber. Вызов Open немедленно вернет клиенту (т. е.) для рендеринга страницы, независимо от того, успешен он или нет. В то же время другой поток будет выполнять операции входа в систему и создания новой учетной записи. После успеха будет запущено событие обратного вызова, поэтому обратный вызов будет выполнен только после отображения страницы, что не соответствует желаемой логике. Мы называем поток, который вызывает Open: поток Jabber, а поток, выполняющий вход в систему, — вспомогательный поток потока Jabber.
Моя первоначальная идея заключалась в использовании Monitor, код:
частный объект objlock=новый объект();
public void RegisterJab (строковое имя пользователя, строковый пароль, строковый сервер)
{
_connection.Server = сервер;
_connection.Имя пользователя = имя пользователя;
_connection.Пароль = пароль;
_connection.Порт = 80;
_connection.UseSSL = ложь;
_connection.AutoResolveConnectServer = true;
_connection.ConnectServer = ноль;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = правда;
_connection.RegisterAccount = правда;
Moniter.Enter(объектблокировка);
_соединение.Открыть();
Moniter.Wait(objlock);
_соединение.Закрыть()
}
частная пустота XmppCon_OnRegistered (отправитель объекта)
{
IsSuccessfull = правда;
Moniter.Exit(objlock);
}
При выполнении Monitor.Exit(): SynchronizationLockException будет выдано исключение, поскольку вспомогательный поток Jabber не является владельцем блокировки. Обнаружено, что Monitor подобен критической секции и не подходит для обработки этой ситуации.
Позже, перенесенный в Mutex, Mutex: представляет собой примитив синхронизации, который предоставляет монопольный доступ к общему ресурсу только одному потоку. Если один поток захватывает мьютекс, второй поток, захвативший мьютекс, будет приостановлен до тех пор, пока первый поток не освободит мьютекс.
Mutex очень подходит для реализации этой функции, но есть ли более простой способ? Это AutoResetEvent: позволяет потокам взаимодействовать друг с другом посредством сигнализации. Обычно это взаимодействие включает в себя ресурсы, к которым потоку необходим монопольный доступ. Самое главное, что он обеспечивает метод связи между потоками, чтобы можно было более гибко управлять шагами вызова потока. Мы используем семафор.
Код:
пространство имен LoginBase
{
Регистрация публичного класса
{
XmppClientConnection_connection;
статический AutoResetEvent myResetEvent;
public bool IsUsed;
общественныйрегистр()
{
_connection = новый XmppClientConnection ();
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.OnLogin += новый ObjectHandler(XmppCon_OnLogin);
_connection.OnRegisterError += новый OnXmppErrorHandler(XmppCon_OnRegErr);
_connection.OnRegistered += новый ObjectHandler(XmppCon_OnRegistered })
;
public bool IsSuccessfull = false;
public void RegisterJab (строковое имя пользователя, строковый пароль, строковый сервер)
{
_connection.Server = сервер;
_connection.Имя пользователя = имя пользователя;
_connection.Пароль = пароль;
_connection.Порт = 80;
_connection.UseSSL = ложь;
_connection.AutoResolveConnectServer = true;
_connection.ConnectServer = ноль;
_connection.SocketConnectionType = agsXMPP.net.SocketConnectionType.Direct;
_connection.UseStartTLS = правда;
_connection.RegisterAccount = правда;
myResetEvent = новый AutoResetEvent (ложь);
_соединение.Открыть();
myResetEvent.WaitOne(20 * 1000, правда);
_соединение.Закрыть()
}
частная пустота XmppCon_OnRegistered (отправитель объекта)
{
IsSuccessfull = правда;
myResetEvent.Set();
}
Private void XmppCon_OnLogin (отправитель объекта)
{
IsSuccessfull = правда;
myResetEvent.Set();
}
частная пустота XmppCon_OnRegErr (отправитель объекта, элемент e)
{
//Если errCode равен 409, пользователь уже существует
IsSuccessfull = ложь;
Элемент xn = e.SelectSingleElement("ошибка");
если (xn.Attribute("код") == "409")
Использовано = правда;
myResetEvent.Set()
}
;
}
}
Сначала установите его в незавершенное состояние, затем войдите в поток Jabber, заблокируйте поток Asp и подождите. Таймаут составляет 20 секунд. Если событие обратного вызова инициируется, статус устанавливается на завершение, и поток asp продолжает выполнение.
Синхронизация завершается успешно, поэтому поток Asp не продолжит работу до тех пор, пока не завершит выполнение вспомогательный поток Jabber.
http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html