我有以下测试代码,首先尝试在无效地址上打开ServiceHost,然后当它出现故障时调用Abort()
和Dispose
(后者可能不需要) 。然后它创建一个新的ServiceHost并尝试在另一个(有效)地址上打开它,但它仍然会生成错误,说明旧地址无效。
class Program
{
static void Main(string[] args)
{
TestHost("net.tcp://0.0.0.1:8081/TestUri");
TestHost("net.tcp://0.0.0.0:8081/TestUri");
}
static void TestHost(string address)
{
ServiceHost host = null;
try
{
host = new ServiceHost(typeof(MyContract), new Uri(address));
host.Open();
Console.WriteLine("Host opened successfully");
host.Close();
}
catch (Exception ex)
{
if (host != null)
{
host.Abort();
((IDisposable)host).Dispose();
}
Console.WriteLine(ex.Message);
}
}
}
[ServiceContract]
public interface IMyContract
{
[OperationContract]
void Method();
}
class MyContract : IMyContract
{
public void Method()
{
Console.WriteLine("Method Called");
}
}
这会生成以下输出:
A TCP error (10049: The requested address is not valid in its context) occurred while listening on IP Endpoint=0.0.0.1:8081.
A TCP error (10049: The requested address is not valid in its context) occurred while listening on IP Endpoint=0.0.0.1:8081.
请注意,两个错误中的端点都是相同的。 (如果我反向操作,第一个调用将成功,第二个调用将失败。)
这里似乎是一些缓存,但是如何清除它并让新的ServiceHost使用我提供的地址而不是旧地址?!
答案 0 :(得分:2)
我不确定我是否也有很多帮助,除了指出其他人遇到类似问题但没有明显的解决方案。
建议:我发现对Close()
的调用不会立即关闭整个堆栈,直到实际的套接字;它会在几秒钟后发生。通常这表示当您尝试在关闭端口后立即重新打开端口时,端口正在使用时会出现错误。我想知道你的测试代码中是否有类似的东西,第二个调用是试图重新打开以前的主机,因为它仍然在某个地方浮动,直到它被整理。尝试在调用TestHost
和/或强制垃圾收集之间加入延迟,看看是否会改变行为。
一个问题:您是否需要绑定到特定的IP地址?在什么情况下它可能无效并且您可以重试不同的地址?你能绑定到所有地址(例如:net.tcp:// localhost:8081 / TestUri)?
答案 1 :(得分:0)
我不确定为什么会发生这种情况,但是绕过它的方法是在有效调用的URI中指定一个端口。
host = new ServiceHost(typeof(MyContract), new Uri("net.tcp://0.0.0.0:8081/TestUri"));
或者您可以在第一次通话时指定特定端口。