为什么WCF回调抛出异常(nettcpbinding)? [英] Why is WCF callback throwing exception (nettcpbinding)?

查看:154
本文介绍了为什么WCF回调抛出异常(nettcpbinding)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个WCF问题回调崩溃后,回调工作正常20次没有任何问题。回拨崩溃时出现错误

Hi,
I have a problem with a WCF Call back crashing after the callback works fine about 20 times without any issues. The call back crashes with the error

<pre>The message could not be transferred within the allotted timeout of 00:00:20. There was no space available in the reliable channel's transfer window. The time allotted to this operation may have been a portion of a longer timeout.





我将开始在下面描述我的代码。请查看。



我有合同,如下所示。



I am going to start describing my code below. Please review.

I have a Contract as shown below.

  [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack1))]
    public interface IService1
    {
         [OperationContract(IsOneWay = true)]
         void StartSlot( int slotNumber);
      

    }

    [ServiceKnownType(typeof(Gen5.Model.STBTestModel))]
    public  interface ICallBack1
    {
         [OperationContract(IsOneWay = true )]
         void TestUpdateEvent(Gen5.Model.STBTestModel stb1);      
         [OperationContract(IsOneWay = true)]
         void UpdateLogBasic(int slot,string text,string testType);
         [OperationContract(IsOneWay = true)]
         void UpdateLogDetailed(int slot,string text,string testType);
         [OperationContract(IsOneWay = true)]
         void UpdateLogBasicandDetailed(int slot, string text, string testType);

     }

I create a proxy client using the code below. Please note the parameters for the proxy client. I also have the server defined further way below in code.

<pre> public class Proxy1
    {
          private EndpointAddress _endPointAddress;
          private NetTcpBinding _tcpBinding ;
          InstanceContext _mContext;
          System.ServiceModel.DuplexChannelFactory<IService1> proxy;
          IService1 proxyfunction;

          public Proxy1(InstanceContext context, string serviceName, string destIPAddresss, int portNumber,TimeSpan sendTimeOut,TimeSpan recieveTimeOut, TimeSpan openTimeOut, TimeSpan closeTimeOut)
          {
              _mContext = context;              
              _tcpBinding = new NetTcpBinding(SecurityMode.None, true);
              _tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
              _tcpBinding.ReliableSession.Ordered = true;
              _tcpBinding.ReliableSession.Enabled = true;
              _tcpBinding.ReliableSession.InactivityTimeout = new TimeSpan(24, 0, 0);
              _tcpBinding.Security.Mode = SecurityMode.None;
              _tcpBinding.OpenTimeout = openTimeOut;
              _tcpBinding.CloseTimeout = closeTimeOut;
              _tcpBinding.TransactionFlow = false;
              _tcpBinding.TransferMode = TransferMode.Buffered;
              _tcpBinding.SendTimeout = sendTimeOut;
              _tcpBinding.ReceiveTimeout = recieveTimeOut;           
              _tcpBinding.MaxConnections = 1000;
              _tcpBinding.ListenBacklog = 1000;
              _tcpBinding.MaxBufferSize = 1000000;//1MB
              _tcpBinding.MaxReceivedMessageSize = 1000000;//1MB
              _endPointAddress = new EndpointAddress("net.tcp://" +/*"10.248.1.3"*/destIPAddresss + ":" +portNumber.ToString() + "/" +"Service"/*serviceName.ToString()*/);
              proxy = new DuplexChannelFactory<IService1>(_mContext, _tcpBinding);
              proxyfunction = proxy.CreateChannel(_endPointAddress);
          }







代理对象在另一个类'Controller'中初始化,这是CallBackClass也如下所示。这个'Controller'类实现'Gen5.WCF.ICallBack1'。如下所示的超时设置是(构造函数如上所示)。 send-20seconds,接收-24小时,opentimeout = 4秒,closetimeout = 4秒。客户端连接到服务器的一个服务,并回拨给同一个客户端。所以这是一对一的设置。






The proxy object is initialized in another class 'Controller' which is the CallBackClass also as shown below. This 'Controller' class implements the 'Gen5.WCF.ICallBack1'. The timeout settings as shown below are (the constructor is shown above ). send-20seconds, receive-24 hours, opentimeout=4 seconds, closetimeout=4 seconds. The client is connecting to one service the server and is calling back to the same client back. So it is a one to one setup.

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
   public class Controller : Gen5.WCF.ICallBack1, Gen5.View.IController
   {




void CreateProxy(int slotNumber)
        {
            string ipTestPC = Shared.Functions.GetTestPCIP(slotNumber);
            proxy1 = new Gen5.WCF.Proxy1(new InstanceContext(this), "Service", ipTestPC, 4000, new TimeSpan(0, 0, 20),new TimeSpan(24, 0, 0), new TimeSpan(0, 0, 4), new TimeSpan(0, 0, 4));
        }







这是客户端连接服务器的连接代码。我叫Start功能。此代码在同一个CallBack接口类Controller上执行。






This is the connection code on the client side to connect to the server. The I call Start function. This code executes on the same CallBack interface class Controller.

proxy1[i].Connect();
proxy1[i].Start();





在ServerSide上,Connect在TestPCController中创建回调上下文,实现'IService1'和Start函数调用一个启动USER Interface Test的线程。这是一个非阻塞,因为它是一个线程。请注意以下代码中服务器的所有超时和设置,但我将其设置为相同。





On the ServerSide, the Connect creates the call back context in TestPCController which implements the 'IService1' and the Start function calls a thread which starts a USER Interface Test. This is non blocking since its a thread. Please note all the timeouts and settings for the server in the code below but I set it up the same.

public partial class TestPCController : Gen5.WCF.IService1, ITestPCController
    {
        #region WCF
        ServiceHost host;
        InstanceContext context;
        NetTcpBinding binding1;
        ServiceThrottlingBehavior throttle;
        public delegate void Gen5TestPCLogUpdateEvent(object sender, int slot, string log, string testTitle, Shared.enumLogType logType);
        public static Gen5TestPCLogUpdateEvent TestPCLogUpdateEvent;
        static IGen5TestPCView viewTestPC;
        static STBTestModel stb;        
        static Devices devicesLocalTestPC;
        public TestPCController()
        {
        }
        public TestPCController(IGen5TestPCView viewGen5TestPC1)
        {
            viewTestPC = viewGen5TestPC1;
        }
        public void StartService(TimeSpan sendTimeOut, TimeSpan recieveTimeOut, TimeSpan openTimeOut, TimeSpan closeTimeOut)
        {

            string uri1 = "net.tcp://localhost" + ":4000/" + "Service";
            host = new ServiceHost(typeof(TestPCController), new Uri(uri1));
            context = new InstanceContext(this);
            binding1 = new NetTcpBinding(SecurityMode.None, true);
            binding1.Security.Message.ClientCredentialType = MessageCredentialType.None;
            binding1.ReliableSession.Ordered = true;
            binding1.ReliableSession.Enabled = true;
            binding1.ReliableSession.InactivityTimeout = new TimeSpan(24, 0, 0);
            binding1.SendTimeout = sendTimeOut;
            binding1.ReceiveTimeout = recieveTimeOut;
            binding1.OpenTimeout = openTimeOut;
            binding1.CloseTimeout = closeTimeOut;
            binding1.MaxBufferSize = 1000000;//1MB
            binding1.MaxReceivedMessageSize = 1000000;//1MB
            binding1.MaxConnections = 1000;
            binding1.ListenBacklog = 1000;
            host.AddServiceEndpoint(typeof(Gen5.WCF.IService1), binding1, "");


            throttle = host.Description.Behaviors.Find<ServiceThrottlingBehavior>();
            host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
            if (throttle == null)
            {
                throttle = new ServiceThrottlingBehavior();
                throttle.MaxConcurrentCalls = 1000;
                throttle.MaxConcurrentSessions = 1000;
                throttle.MaxConcurrentInstances = 1000;
                host.Description.Behaviors.Add(throttle);
            }
            host.Open();
            Console.WriteLine("Started Gen5Service at " + uri1 + " successfully");


            STBTestModel.testUpdateEvent += STB_TestUpdateEvent;
            STBTestModel.logEvent += STB_LogEvent;
            STBTestModel.logActionEvent += STBTestModel_logActionEvent;

        }







public void Connect()
       {
           iServiceCallback = OperationContext.Current.GetCallbackChannel<Gen5.WCF.ICallBack1>();

       }

       public void StartSlot(int slotNumber)
       {

       }





使用回调调用大约4个不同的函数。他们回调函数连续调用至少50次然后崩溃。我知道它不是客户端上的UI阻塞,因为回调函数不执行任何代码 - 它暂时是空白 - 它仍然崩溃。我的代码中的某些内容是错误的,导致回调在某些时候崩溃。 Rentrant等我不知道为什么回叫会崩溃。我知道回调只被怀疑一次 - 服务器可以回拨的次数有限制。我注意到的唯一奇怪的事情是代码每次都完全挂在同一行。由于客户端的回调代码中没有代码,我知道它的WCF相关。有些东西导致回叫超时,这是一个固定的事件。



请分享您的想法,并随时提出任何问题。我试着尽可能地清楚。



我尝试过的事情:



我尝试了所有不同的组合,如Concurrent.Muliple,Rentrant等。



我尝试做一个跟踪,但跟踪只显示Service.Model抛出异常和崩溃。



我从客户端回调执行中删除了所有代码,以确保它不是客户端的UI Block。



我在服务器和客户端上添加了以下代码用于绑定





About 4 different functions are called using callback. They call back functions get called at least 50 times in a row and then crashes. I know its not UI blocking on the client because the callback functions dont execute any code- its blank temporarily- it still crashes. Something in my code is wrong that causes the callback to crash at some point. Rentrant etc. I have no idea why the call back is crashing. I know that the callback is only suscribed to once- is there a limit on how many times server can call back using. The only weird thing I noticed is that the code hangs exactly at the same line everytime. Since there is no code in the callback code in the client, I know its WCF related. Something is causing the call back to timeout and it is a fixed event.

Please share your thoughts and don't hesitate to ask any questions please. I tried to be as clear as I could.

What I have tried:

I tried all different combinations like Concurrent.Muliple, Rentrant etc.

I tried doing a trace but the trace only shows the Service.Model throwing exception and crashing.

I removed all code from the client call back execution to make sure it was not a UI Block on the client side.

I added the following code for binding on both server and client

binding1.ReliableSession.Ordered = true;
          binding1.ReliableSession.Enabled = true;
          binding1.ReliableSession.InactivityTimeout = new TimeSpan(24, 0, 0);
          binding1.TransactionFlow = false;
          binding1.TransferMode = TransferMode.Buffered;





我把同步context = false



I put synchronization context = false

推荐答案

WOOOOO。经过2天的故障排除后,最终解决了这个问题。



我做了以下修复问题。但是我不确定哪个步骤解决了这个问题。我需要深入挖掘才能找到,但想在忘记之前发布这个。



1)我的客户端CallBack类构造函数没有默认构造函数。如上所述,这可能会导致问题。

WCF - 以更高的并发性提高性能theburningmonk.com [ ^ ]



2)我增加了_tcpBinding.MaxConnections = 10000和

_tcpBinding.ListenBacklog = 10000;为了以防万一。

我还增加了以下内容:

WOOOOO. Solved the issue finally after 2 days of troubleshooting.

I did the following to fix the issues. However I am not exactly sure which step fixed the issue. I would need to dig in more to find that but wanted to post this before I forget.

1) My client CallBack class constructor did not have a default constructor.
as noted here, this can cause issues.
WCF – Improve performance with greater concurrency | theburningmonk.com[^]

2) I increased the _tcpBinding.MaxConnections = 10000 and
_tcpBinding.ListenBacklog = 10000; just in case.
I increased the following also:
_tcpBinding.MaxBufferSize = 100000000;//100MB
             _tcpBinding.MaxReceivedMessageSize = 10000000;//100MB





3)我实现了下面的同步



[< a href =https://support.microsoft.com/en-us/help/2538826/wcf-service-may-scale-up-slowly-under-loadtarget =_ blanktitle =New Window> ^ ]



4)我增加了客户端和服务器上的线程池

为什么WCF响应缓慢且SetMinThreads不起作用? - Wenlong Dong的博客 [ ^ ]



5)我已经在服务器上安装了servertrace将以下配置放在server nad client的app.config中之后。这只是一个故障排除工具,现在我可以确认我的wcf调用和回调平均只需4ms(这是本地通信服务器客户端)。我处理了500多个回调,没有任何问题。我将把它放在一个循环中一天,看看会发生什么。





3) I implemented the synchronization below

[^]

4) I increased the threadpool on both client and server
Why Are WCF Responses Slow and SetMinThreads Does Not Work? – Wenlong Dong's Blog[^]

5) I had already installed the servertrace on the sever after putting the below configurations in app.config of server nad client. This is just a troubleshooting tool and now I can confirm that my wcf calls and callbacks only take 4ms average(This is a local communication server client). I processed over 500 callbacks without any issue. I am going to put it in a loop for a day and see what happens.

<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\wcflog\traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <system.net>
    <defaultProxy>
      <proxy usesystemdefault="False"/>
    </defaultProxy>
  </system.net>
 
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>





如果我有任何更新,我会发布但是很快。



If I have any updates I will post but whew.

这篇关于为什么WCF回调抛出异常(nettcpbinding)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆