У меня следующий код метода в приложении Xamarin.Forms
using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
{
byte[] messageBytes = PrepareMessageBytes();
//
// Setting these seam to have no effect
//
stream.WriteTimeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
stream.ReadTimeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
//
// I have set read and write timeouts above but when
// hitting this line, app hangs indefinitely?
// I would expect that after 10 seconds, a IOException
// will be thrown
await stream.WriteAsync(messageBytes, 0, messageBytes.Length);
stream.Flush();
byte[] buffer = new byte[1024];
StringBuilder builder = new StringBuilder();
int bytesRead = 0;
while (stream.DataAvailable)
{
bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
}
string msg = receivedMessage.ToString();
}
Выше я установил тайм-ауты для записи и чтения на 10 секунд.Я знаю, что мой код зависает при вызове:
await stream.WriteAsync (...)
, но я ожидаю, что через 10 секунд будет сгенерировано исключение IOException.Основываясь на документации MS, это не относится к асинхронным операциям записи / чтения.
Как установить тайм-аут для вызовов методов WriteAsync / ReadAsync?
ОБНОВЛЕНИЕ - 2-Й ПОПЫТКА, ОСНОВАННАЯ НАКОММЕНТАРИЙ СТЕФЕНА
Основываясь на комментарии Стивена, я обновил код и включил его в try..catch для обработки исключения OperationCancelledException. Но это вызывает еще больше проблем, чем раньше, и приложение по-прежнему будет зависать большую часть времени :
try
{
using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
using (var writeCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
{
byte[] messageBytes = PrepareMessageBytes();
await stream.WriteAsync(messageBytes, 0, messageBytes.Length, writeCts.Token);
await stream.FlushAsync();
byte[] buffer = new byte[1024];
StringBuilder builder = new StringBuilder();
int bytesRead = 0;
while (stream.DataAvailable)
{
using (var readCts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, readCts.Token);
builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, bytesRead));
}
string msg = receivedMessage.ToString();
}
catch (OperationCancelledException ex)
{
Debug.WriteLine(ex.Message);
}