2016-08-03 161 views
0

我知道这里有100万个帖子,但我不明白这个。 我有一个极值简单的例子管道服务:Mysterious =>从管道读取时发生错误:管道已结束。 (109,0x6d)

​​

当我把它的人,一切都很好,但是当两个客户端同时调用它会抛出该异常。 服务器直接设置一个新线程并返回给客户端。

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秒的时间。尤其是当我在同步称它为环路从我的单元测试

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跟踪。在这里我可以看到每次调用抛出异常。详细信息窗格根本没有帮助我,因为它向我显示两次异常=> 从管道读取时发生错误:管道已结束。 (109,0x6d)。

enter image description here

随着不同的堆栈跟踪=>

enter image description here

enter image description here

我也看到在DebugView中的例外来长后拨回是在客户端。 我的问题是:

  1. 为什么服务工作,因为即使当它抛出这个异常

  2. 我怎样才能摆脱例外的,因为他们都得到日志文件和我expectet我不会感冒。

THX迈克尔

+0

没有这个例子,没有人可以帮助你。您可能想编辑帖子。 –

+0

哈哈 - 我无法添加所有的内容。所以我做了一些步骤。 –

回答

0

我们已经看到了这样的行为是由于如何命名管道池在WCF内部实现。在我们的例子中,这些例外或多或少是随机的(不是每次调用之后),但是在研究MS参考资源后,我们认为它们是不可避免的。你提到“在客户回来之后很久就会发生例外情况”,这让我认为你正在观察同样的行为。

您可以看到hereNamedPipeConnectionPoolSettings的“证明”:IdleTimeout设置为某个默认值,即等于2 minutes

也许我们错了我们的决定,这是不可避免的,因为我现在看到NamedPipeConnectionPoolSettings类是公共和IdleTimeout属性也是公共的,可以被设置为TimeSpan.MaxValue应防止管道和这些异常关闭。

希望这会有所帮助。

0

我得到这个相同的序列异常与非常相似的跟踪数据,并且在将绑定更改为以下异常停止后。请注意,我不知道这些更改的含义是什么,请谨慎使用。

public Binding GetBinding() 
    { 
     var binding = new NetNamedPipeBinding 
     { 
      OpenTimeout = TimeSpan.FromMinutes(15), 
      SendTimeout = TimeSpan.FromMinutes(15), 
      CloseTimeout = TimeSpan.FromMinutes(15), 
      MaxConnections = 200, 
      MaxBufferSize = int.MaxValue, 
      MaxReceivedMessageSize = int.MaxValue, 
      MaxBufferPoolSize = int.MaxValue, 
      TransactionFlow = false, 
      TransactionProtocol = TransactionProtocol.WSAtomicTransaction11, 
      TransferMode = TransferMode.StreamedRequest, 
      HostNameComparisonMode = HostNameComparisonMode.WeakWildcard 
     }; 
     binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
     return binding; 
    }