WCF generating high computer usage and network storm

Article translations Article translations
Article ID: 2786802 - View products that this article applies to.
Expand all | Collapse all

On This Page

About Author:

Collapse this tableExpand this table
Collapse this imageExpand this image
MVP
Leo Lorenzo Luis is a Microsoft MVP, he has also been a Microsoft Student Partner from 2009 to 2011, and became a Worldwide Imagine Cup Finalist to represent the Philippines for 2011 that was held in New York, United States. He is passionate in developing applications in the .NET Framework and has been helping the community to share his expertise and knowledge about the technology. More about Leo on his website http://www.luisleo.net

Symptoms

When using Windows Communication Foundation (WCF) support for WS-Discovery over UDP, you may see one or more of the following problems:

1.) Hits the following exception in an infinite loop

Collapse this tableExpand this table
Type: ArgumentException
Message: The 'result' argument must be of type Message
Stack trace:
at System.ServiceModel.Dispatcher.MessageOperationFormatter.SerializeReply(MessageVersion messageVersion, Object[] parameters, Object result)

2.) Network storms

3.) Generates a high CPU usage even after FindCompleted is called

4.) Keeps sending SOAP Fault exception being sent over with .NET 4.5

5.) High multicast traffic

Cause

1. Microsoft internal bug in the WCF Framework 4.0

2. WCF keeps sending fault exceptions

3. The WCF service hosts multiple UDP Multicast Services where more than one service shares a given multicast address and port

Resolution

To resolve this issue, apply one of the updates that are described in the following Knowledge Base (KB) articles:
  • 2805226 An update is available for the .NET Framework 4.5 in Windows 7 SP1, Windows Server 2008 R2 SP1, Windows Server 2008 SP2, and Windows Vista SP2: May 2013
  • 2805227 An update is available for the .NET Framework 4.5 in Windows 8, Windows RT, and Windows Server 2012: May 2013
Note For more information about this issue, see "Issue 2" in the "WCF" section.

Workarounds

There are a lot of different ways to solve this problem for now and Microsoft is aware of the bug and will release a hot fix soon.

  1. First Workaround

    The first work around is first discovered by Michael A. Shields (Pyramid Systems, Inc.) Developer. It is just basically uses reflection and this was a work around that removes the "System.ServiceModel.Discovery.UdpContractFilterBehavior" in the Behaviors of the endpoint.
    Collapse this tableExpand this table
    AnnouncementService announcementService = new AnnouncementService();
    var endpoint = new UdpAnnouncementEndpoint();
    var behavior = endpoint.Behaviors.FirstOrDefault(e => e.GetType().FullName == "System.ServiceModel.Discovery.UdpContractFilterBehavior");
    if (behavior != null) endpoint.Behaviors.Remove(behavior);
    ServiceHost host = new ServiceHost(announcementService);
    host.AddServiceEndpoint(endpoint);
    host.Open();
  2. Second Workaround

    The second work around is made by Wayne Xiong (Microsoft). Instead of using reflection we create a custom behavior and use that class when using a UdpAnnouncementEndPoint and add it to it's behaviors. Which is where the first work around came from.

    CustomBehaviorClass.cs
    Collapse this tableExpand this table
    class WorkaroundBehavior : IEndpointBehavior
    {
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
     {
            
     }        
    
    
     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
     {
      if (clientRuntime == null)
      {
        throw new ArgumentNullException("clientRuntime");
      }
      clientRuntime.CallbackDispatchRuntime.UnhandledDispatchOperation.Invoker = new UnhandledActionOperationInvoker();
     }
    
     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
     {
     }
    
     public void Validate(ServiceEndpoint endpoint)
     {
     }
    
     class UnhandledActionOperationInvoker : IOperationInvoker
     {
      public bool IsSynchronous
      {
       get
       {
        return true;
       }
      }
    
     public object[] AllocateInputs()
     {
      return new object[1];
     }
    
     public object Invoke(object instance, object[] inputs, out object[] outputs)
     {
      outputs = new object[0];
      return Message.CreateMessage(MessageVersion.None, string.Empty);
     }
    
     public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
     {
      throw new NotImplementedException();
     }
    
     public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
     {
      throw new NotImplementedException();
     }
     }
    }

    MainWindow.cs
    Collapse this tableExpand this table
    UdpDiscoveryEndpoint clientEndpoint = new UdpDiscoveryEndpoint();
    clientEndpoint.Behaviors.Add(new WorkaroundBehavior());
    var discoveryClient = new DiscoveryClient(clientEndpoint);
    Note from Wayne Xiong :
    If you do not have access to the server-side code, you can add the following on the client-side instead. Add this behavior to your client-side UdpDiscoveryEndpoint. This workaround must be applied to all Discovery clients whether they are compiled in .NET 4.5 or in .NET 4.0
  3. Third Workaround

    Use a unique multicast address and/or port for each service listening on the SOAP.UDP protocol.
  4. Fourth Workaround

    The last work around is from Jon Cole (Microsoft). Programmatically force the transport to use duplex channel, instead of the IReplyChannel that was introduced in 4.5. Following is a C# code sample to accomplish this on the service side (on the server). Using the following class, we can have a custom implementation of CanBuildChannelListener that returns false for IReplyChannel:

    CustomClass.cs
    Collapse this tableExpand this table
    class DisableIReplyChannelShapeBindingElement : BindingElement
    {
        public override BindingElement Clone()
        {
            return this;
        }
    
        public override T GetProperty<T>(BindingContext context)
        {
            return null;
        }
    
        public override bool CanBuildChannelListener<TChannel>(BindingContext context)
        {
            if (typeof(TChannel) == typeof(IReplyChannel))
            {
                return false;
            }
            return context.CanBuildInnerChannelListener<TChannel>();
        }
    }
    By inserting this into the binding, your application can hide the fact that the UDP transport supports the IReplyChannel shape from the Announcement endpoint, which will avoid the problem. Following is a helper method that will be used later:

    HelperClass.cs

    Collapse this tableExpand this table
    public static void DisableIReplyChannelShape(ServiceEndpoint endpoint)
    {
        CustomBinding customBinding = new CustomBinding(endpoint.Binding);
        //only do this if using the UdpTransport.
        if (customBinding.Elements.Find<UdpTransportBindingElement>() != null)
        {                
            customBinding.Elements.Insert(customBinding.Elements.Count - 1, new DisableIReplyChannelShapeBindingElement());
            endpoint.Binding = customBinding;
        }            
    }
    You can stop your server-side code from sending the fault messages that are causing problems by doing the following to your AnnouncementEndpoint:

    Collapse this tableExpand this table
    UdpAnnouncementEndpoint announcementEndpoint = new UdpAnnouncementEndpoint();
    DisableIReplyChannelShape(announcementEndpoint);

Community Solutions Content Disclaimer

MICROSOFT CORPORATION AND/OR ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY, RELIABILITY, OR ACCURACY OF THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN. ALL SUCH INFORMATION AND RELATED GRAPHICS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT AND/OR ITS RESPECTIVE SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THIS INFORMATION AND RELATED GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE EFFORT, TITLE AND NON-INFRINGEMENT. YOU SPECIFICALLY AGREE THAT IN NO EVENT SHALL MICROSOFT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE, INCIDENTAL, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT OF OR IN ANY WAY CONNECTED WITH THE USE OF OR INABILITY TO USE THE INFORMATION AND RELATED GRAPHICS CONTAINED HEREIN, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF MICROSOFT OR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES.

Properties

Article ID: 2786802 - Last Review: September 25, 2013 - Revision: 7.1
Applies to
  • Windows Communication Foundation 4
  • Windows Communication Foundation 4.5
Keywords: 
kbstepbystep kbmvp kbcommunity KB2786802

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com