Работя с доста специфично Web API, което използва TCP и SSL stream. Връзката с апито е постоянна(не се затваря след всяко четене/писане), защото по нея се получават известия от сървъра.
Имплементирах следния метод за четене:
private void Listen()
{
int length;
do
{
var buffer = new byte[TcpClient.ReceiveBufferSize];
length = SslStream.Read(buffer, 0, TcpClient.ReceiveBufferSize);
if (length > 0)
{
// обработка на данните
Listen();
}
} while (length > 0);
// свързване отново
}
Сега трябва да извикам някои методи от апито. Искам да поддържат TPL(async/await). Проблемът е, че асинхронните части на тези методи са имплементирани в горния метод. Например:
public async Task<bool> Authenticate(string clientId, string clientSecret)
{
await SendAuthMessageOverNetwork(clientId, clientSecret);
return await ReceiveAuthResponseFromServer();
// Проблемът е че няма метод ReceiveAuthResponseFromServer
//отговорът се получава в четящата нишка
}
Не съм много запознат с TPL. Реших този проблем като използвах Task,което не прави нищо освен да изчаква сигнал (AutoResetEvent) от четящата нишка:
private AutoResetEvent _loginEvent;
private bool _loginResult;
public async Task<bool> Authenticate(string clientId, string clientSecret)
{
await SendAuthMessageOverNetwork(clientId, clientSecret);
return await Task<bool>.Factory.StartNew(() => { _loginEvent.WaitOne(); return _loginResult; });
}
private void Listen()
{
...
if (msg.Type == MessageTypes.AuthenticationResponse)
{
_loginResult = true;
_loginEvent.Set();
}
...
}
Но така не ми харесва. Сигурно има и по-прост начин да се направи? Може ли да се направи само с функционалностите на Task, без AutoResetEvent и междинна глобална променлива?