Ответ 1
Вы можете обернуть вызов в реализации IAsyncResult. Поскольку я смотрел многопоточность в последнее время, я опубликовал ее здесь (у нее есть ссылки на другие реализации интерфейса):
Я изучаю добавление некоторой гибкости классу, который я создал, который устанавливает соединение с удаленным хостом, а затем выполняет обмен информацией (рукопожатие). Текущая реализация обеспечивает функцию Connect, которая устанавливает соединение, а затем блокирует ожидание в ManualResetEvent до тех пор, пока обе стороны не завершили квитирование.
Вот пример того, как выглядит мой класс:
// create a new client instance
ClientClass cc = new ClientClass("address of host");
bool success = cc.Connect(); // will block here until the
// handshake is complete
if(success)
{
}
.. и здесь упрощенное представление высокого уровня о том, что класс делает внутри:
class ClientClass
{
string _hostAddress;
ManualResetEvent _hanshakeCompleted;
bool _connectionSuccess;
public ClientClass(string hostAddress)
{
_hostAddress = hostAddress;
}
public bool Connect()
{
_hanshakeCompleted = new ManualResetEvent(false);
_connectionSuccess = false;
// start an asynchronous operation to connect
// ...
// ...
// then wait here for the connection and
// then handshake to complete
_hanshakeCompleted.WaitOne();
// the _connectionStatus will be TRUE only if the
// connection and handshake were successful
return _connectionSuccess;
}
// ... other internal private methods here
// which handle the handshaking and which call
// HandshakeComplete at the end
private void HandshakeComplete()
{
_connectionSuccess = true;
_hanshakeCompleted.Set();
}
}
Я изучаю реализацию .NET Classic Async Pattern для этого класса. При этом я предоставлял бы функции BeginConnect и EndConnect и позволял бы пользователям класса писать такой код:
ClientClass cc = new ClientClass("address of host");
cc.BeginConnect(new AsyncCallback(ConnectCompleted), cc);
// continue without blocking to this line
// ..
void ConnectCompleted(IAsyncResult ar)
{
ClientClass cc = ar.AyncState as ClientClass;
try{
bool success = cc.EndConnect(ar);
if(success)
{
// do more stuff with the
// connected Client Class object
}
}
catch{
}
}
Чтобы предоставить этот API, мне нужно создать класс, который реализует интерфейс IAsyncResult, который будет возвращен функцией BeginConnect, и будет передан в функцию EndConnect соответственно.
Теперь, мой вопрос: что такое правильный способ реализации интерфейса IAsyncResult в классе?
Одним из очевидных решений было бы создание делегата с подходящей сигнатурой для функции Connect, а затем асинхронное использование этого делегата с помощью BeginInvoke - EndInvoke, но это не то, что я ищу (это не очень эффективно).
У меня есть приблизительное представление о том, как я мог это сделать, но после того, как увидел в .NET Framework, как они реализуют этот шаблон в некоторых местах, я чувствовал, что было бы разумно спросить и посмотреть, сделал ли кто-нибудь это успешно, и если это так в каких проблемных областях уделять особое внимание.
Спасибо!
Вы можете обернуть вызов в реализации IAsyncResult. Поскольку я смотрел многопоточность в последнее время, я опубликовал ее здесь (у нее есть ссылки на другие реализации интерфейса):
У вас также есть много реализаций в BCL (например, System.Runtime.Remoting.Messaging.AsyncResult
) - используйте отражатель или источник ссылки, чтобы проверить их.