我的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秒。我知道我的代码挂在电话里:
等待stream.WriteAsync(.)
,但我希望10秒后,会抛出一个IOException。基于MS文档,异步写入/读取不是这种情况。
如何设置调用WriteAsync / ReadAsync方法的超时?
更新--基于评论的第二次尝试
根据Stephen的评论,我更新了代码并将其封装到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);
}
发布于 2019-02-22 14:35:03
如何设置调用WriteAsync / ReadAsync方法的超时?
使用接受CancellationToken
参数的重载:
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();
}
我希望10秒后,会抛出一个IOException。
当使用取消令牌时,期望得到一个OperationCanceledException
。从技术上讲,取消令牌可以用于各种各样的取消场景--代码决定不再需要完成操作,用户手动取消操作,或者超时。OperationCanceledException
是泛型异常类型,意思是“取消”。
https://stackoverflow.com/questions/54816114
复制相似问题