如何在StreamSocket's ConnectAsync()上设置超时值

本文关键字:设置 超时 ConnectAsync StreamSocket | 更新日期: 2023-09-27 18:19:22

在Windows Phone 8.1应用程序中,我必须创建我的套接字如下。我如何更改它,使它在我可以指定的一段时间后超时?

_socket = new StreamSocket();
await _socket.ConnectAsync(hostName, port.ToString(), SocketProtectionLevel.PlainSocket);
await _socket.InputStream.ReadAsync(frameLenData, frameLenData.Capacity, Windows.Storage.Streams.InputStreamOptions.None);

在我之前的Windows Phone代码中,我会创建Socket并通过测试_event.WaitOne(timeout)设置超时,例如

timeout = 5000;
_event = new ManualResetEvent(false);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
bool bOperationFailed = false;
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = new DnsEndPoint(address, port);

_event.Reset();
_socket.ReceiveAsync(socketEventArg);
// Wait for completion
if (_event.WaitOne(timeout) == false)
{
    Trace.trace("timed out");
    return false;
}

可以设置StreamSocketConnectAsync()的超时时间吗?如果有,怎么做?

如何在StreamSocket's ConnectAsync()上设置超时值

使用CancellationTokenSourceAsTask扩展方法

var cts = new CancellationTokenSource();
cts.CancelAfter(2000); // cancel after 2 seconds
var connectAsync = _socket.ConnectAsync( ... );
var connectTask = connectAsync.AsTask(cts.Token);
await connectTask;   

由于我没有添加评论的声誉,所以我不得不添加另一个答案。

另一种不需要额外变量的方法:

await socket.ConnectAsync(hostName, port).AsTask(new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token);

我做了以下操作,这似乎对我有效:

if (!_socket.ConnectAsync(uri, CancellationToken.None).Wait(timeout))
{
    // connect timed out
}

我尝试使用esskar的答案/解决方案,但它没有工作,因为,正如前面提到的,在我使用的。net的最新版本中不存在asask()方法。

所以,我稍微调整了一下解决方案,做了以下工作,请检查我的工作,看看这是否符合要求:

using (var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
      var timeout = 1000;
      var cts = new CancellationTokenSource();
      cts.CancelAfter(timeout);
      var connectAsync = sock.ConnectAsync(address, port, cts.Token); // address and port set earlier in scope
      await connectAsync;          
}