我知道这个例外有数百万个帖子,但我不会在这里理解这个。 我有一个极端的简单示例管道服务:
[ServiceContract]
public interface ISRARiskExport
{
[OperationContract(IsOneWay = true)]
void RiskExport(long sraid, long revID, string JobID);
}
当我调用它时,一切都很好但是当两个客户端同时调用它时它会抛出此异常。 服务器直接设置一个新线程并返回给客户端。
public void RiskExport(long sraid, long revID, string JobID)
{
ThreadStarter starter = new ThreadStarter(new ThreadStartWithParameter(RunExportJob), new SRAInfo() { sraid = sraid, revID = revID, JobID = JobID });
Thread t = new Thread(new System.Threading.ThreadStart(starter.ThreadStartEntry));
t.IsBackground = true;
t.Start();
}
因此它不能成为超时问题,因为从cleint到服务器并返回需要1秒。特别是当我从单元测试中同步调用for循环时
string JobID = "";
for (int i = 0; i < 100; i++)
{
string baseAddress = "net.pipe://localhost/SRADocumentService";
ChannelFactory<ISRARiskExport> factory = new ChannelFactory<ISRARiskExport>(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(baseAddress));
ISRARiskExport svc = factory.CreateChannel();
JobID = Guid.NewGuid().ToString();
svc.RiskExport(sraid, revID, JobID);
}
我已准备好激活WCF跟踪。在这里,我可以看到每个调用抛出异常。详细信息窗格根本没有帮助我,因为它向我显示两次异常=&gt; 从管道读取错误:管道已经结束。 (109,0x6d)。
使用不同的堆栈跟踪=&gt;
我还在Debugview中看到,在客户端回调之后很久就会出现异常。 我的问题是:
为什么服务即使在抛出此异常时也会起作用
我怎样才能摆脱异常,因为它们都到达了日志文件,而我却无法抓住它。
THX Michael
答案 0 :(得分:2)
我们已经看到这样的行为,因为命名管道池是如何在WCF内部实现的。在我们的例子中,这些例外或多或少随机地(不是在每次调用之后)在日志中,但在研究MS参考源之后我们认为它们是不可避免的。你提到“在客户回电之后很久就会出现异常”,这让我觉得你正在观察同样的行为。
您可以看到here的“证明”:NamedPipeConnectionPoolSettings
IdleTimeout
设置为某个默认值,等于2 minutes。
我们的决定可能是不可避免的,因为我现在看到NamedPipeConnectionPoolSettings
类是公开的,IdleTimeout
属性也是公开的,可以设置为TimeSpan.MaxValue
,这应该是预防的关闭管道和这些例外。
希望这有帮助。