我只是在学习WCF,尝试不同的东西。
我已经设置了以下服务:
[ServiceBehavior(IncludeExceptionDetailInFaults = true ,
InstanceContextMode = InstanceContextMode.Single)]
public class TestService : ITestService
{
// This operation is defined as OneWay.
public void Throws()
{
throw new ArgumentException();
}
}
我从我的客户那里使用它:
var baseAddress = new Uri("net.pipe://localhost/hello");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(TestService), baseAddress))
{
var netBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
host.AddServiceEndpoint(typeof(ITestService), netBinding, baseAddress);
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
// Create client channel.
var channel = ChannelFactory<ITestService>.CreateChannel(netBinding, new EndpointAddress(baseAddress));
((ICommunicationObject)channel).Open();
try
{
foreach (var i in Enumerable.Range(0, 5000))
{
// channel dies after a few attempts.
channel.Throws();
}
}
方法投掷被定义为IsOneWay = true,这意味着它不会将任何消息传播回客户端(包括错误)。
在循环中运行时,通信对象在一些运行后出现故障。 我无法弄清楚原因。
例外情况:
System.ServiceModel.CommunicationException:写入时出错 到管道:管道正在关闭。 (232,0xe8)。 ---&GT; System.IO.PipeException:写入管道时出错:The 管道正在关闭。 (232,0xe8)。在 System.ServiceModel.Channels.PipeConnection.StartSyncWrite(字节[] 缓冲区,Int32偏移量,Int32大小,对象&amp;持有人) System.ServiceModel.Channels.PipeConnection.Write(Byte [] buffer,Int32 offset,Int32 size,Boolean immediate,TimeSpan timeout,BufferManager bufferManage r)---内部异常堆栈跟踪结束---
请注意,如果我将Throws方法的主体更改为其他内容,例如Console.WriteLine,则一切正常。
编辑:我已将示例项目上传到我的SkyDrive:http://sdrv.ms/NumUbR
如果有人想在本地编译它并查看它是否表现相同。
答案 0 :(得分:5)
您只是在某个时刻超出可用带宽。它可能是管道,但它也可能在WCF堆栈中...处理异常是昂贵的,并且你在尽可能紧的循环中做了5000个。从异常更改为不返回任何内容的WriteLine()
可以解决问题,因为它可以显着减少所需的带宽/处理。 (我确实看到你提到了OneWay,但我认为它没有太大变化。即使没有返回异常,它仍然需要处理)。
尝试将InstanceContextMode更改为PerCall。这是“高容量”服务的标准设置。它将缓解一些的拥堵。
另外,为了解决这些意见,托管这样的服务很好。 ServiceHost将管理自己的线程。