如何在C#中为BeginConnect异步调用设置自定义超时?这是非常有用的,当连接到一个主机时,有可能不监听给定的端口。每个这样的调用在释放线程之前都会浪费大约15s的时间。
我有以下代码,建议在许多stackoverflow答案:
public bool Test()
{
using (var tcp = new TcpClient())
{
var c = tcp.BeginConnect(IPAddress.Parse("8.8.8.8"), 8080, null, null);
var success = c.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));
if (!success)
{
Console.WriteLine("Before cleanup");
tcp.Close();
tcp.EndConnect(c);
Console.WriteLine("After cleanup");
throw new Exception("Failed to connect.");
}
}
return true;
}
然而,这并不起作用。实际上,在调用后,函数进入“if”开关,但它立即阻塞**tcp.Close()**调用,并等待上述15秒。是否可以以某种方式避免?
1条答案
按热度按时间b1uwtaje1#
我编写了一个简单的测试程序,使用两种不同的技术来实现您的目标,同时也测试了您发布的确切代码。我无法重现您所描述的问题。无论是直接使用
TcpClient
还是Socket
,对对象调用Close()
都会导致连接操作立即完成(在完成所有异步完成、异常处理、线程同步等之后,时间不到十分之一秒)请注意,在
TcpClient
的情况下,TcpClient
类似乎有一个bug,它抛出了NullReferenceException
而不是(如人们所期望的)ObjectDisposedException
。这似乎是因为当Close()
被调用时,TcpClient
将Client
属性设置为null
,但随后试图在调用完成委托时使用该值。糟糕。这意味着在代码中,调用者将看到
NullReferenceException
,而不是您似乎想要抛出的Exception
,但这本身似乎不会导致实际延迟。下面是我的测试程序:
不幸的是,你没有提供一个完整的代码示例来演示这个问题。如果在你的环境中,上面的代码演示了你所描述的问题,那么,由于它在我的环境中没有这样做,这显然意味着你的环境中有一些东西导致了这个问题。不同的操作系统版本,不同的.NET版本,等等。
在这种情况下,您应该具体说明环境中可能相关的特定方面。
如果上面的代码示例正常工作,并且没有演示您所描述的问题,那么您只需找出代码中的不同之处并找出问题的原因。在这种情况下,如果您仍然不能真正找出问题所在,那么您应该发布演示问题的a minimal, complete code example。