יום חמישי, 27 ביוני 2013

Wcf discovery high cpu consumption problem

I have encountered a critical problem regarding wcf discovery.
The following WCF code used to try to find services and announce about my services.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.ServiceModel;
  5: using System.ServiceModel.Discovery;
  6: using System.Text;
  7: using System.Threading.Tasks;
  8: 
  9: namespace WpfApplication1
 10: {
 11:     public class OperatorServicesAccessor
 12:     {
 13: 
 14:         private AnnouncementService mAnnouncementService;
 15:         private ServiceHost mAnnouncementServiceHost;
 16:         UdpAnnouncementEndpoint mUdpAnnouncementEndpoint;
 17: 
 18:         private static OperatorServicesAccessor mOperatorServicesAccessor = new OperatorServicesAccessor();
 19: 
 20:         public static OperatorServicesAccessor Instance()
 21:         {
 22:             return mOperatorServicesAccessor;
 23:         }
 24: 
 25:         private OperatorServicesAccessor()
 26:         {
 27: 
 28:         }
 29: 
 30:         public void Init()
 31:         {
 32: 
 33:             StartScanForeOperatorEntities();
 34: 
 35:             OpenAnnouncementService();
 36:         }
 37: 
 38:         /// <summary>
 39:         /// When the client recevied non aplication exception it close the channel 
 40:         /// and wait for the service to start itself 
 41:         /// </summary>
 42:         /// <param name="pFaultedChannel"></param>
 43:         /// <param name="pEx"></param>
 44:         public void ReportAboutFaultedClient(object pFaultedChannel, Exception pEx)
 45:         {
 46: 
 47:             if (pFaultedChannel == null)
 48:             {
 49:                 return;
 50:             }
 51: 
 52:             if (pEx is ProtocolException)
 53:             {
 54: 
 55:             }
 56: 
 57:             if (pEx is CommunicationException)
 58:             {
 59: 
 60:             }
 61: 
 62:         }
 63: 
 64:         void mDiscoveryClient_FindCompleted(object sender, FindCompletedEventArgs e)
 65:         {
 66:             try
 67:             {
 68: 
 69:                 switch (e.UserState.ToString())
 70:                 {
 71:                     case "IOperator":
 72: 
 73:                         foreach (EndpointDiscoveryMetadata nextEndpointDiscoveryMetadata in e.Result.Endpoints)
 74:                         {
 75:                             EndpointAddress theAddress = nextEndpointDiscoveryMetadata.Address;
 76: 
 77:                             return;
 78:                         }
 79:                         break;
 80:                 }
 81:             }
 82:             catch (Exception ee)
 83:             {
 84: 
 85:             }
 86:             finally
 87:             {
 88:                 ((DiscoveryClient)sender).Close();
 89:             }
 90: 
 91:         }
 92: 
 93:         private void StartScanForeOperatorEntities()
 94:         {
 95: 
 96:             UdpDiscoveryEndpoint mUdpDiscoveryEndpoint = new UdpDiscoveryEndpoint();
 97: 
 98:             DiscoveryClient mDiscoveryClient = new DiscoveryClient(mUdpDiscoveryEndpoint);
 99: 
100:             mDiscoveryClient.FindCompleted += new EventHandler<FindCompletedEventArgs>(mDiscoveryClient_FindCompleted);
101: 
102:             FindCriteria criteria = new FindCriteria(typeof(IOperator));
103: 
104:             criteria.Duration = TimeSpan.FromSeconds(5);
105: 
106:             mDiscoveryClient.FindAsync(criteria, "IOperator");
107: 
108:         }
109: 
110:         private void OpenAnnouncementService()
111:         {
112:             mAnnouncementService = new AnnouncementService();
113:             // Add event handlers
114: 
115:             mAnnouncementService.OnlineAnnouncementReceived +=
116:                 new EventHandler<AnnouncementEventArgs>(this.OnOnlineAnnouncement);
117:             mAnnouncementService.OfflineAnnouncementReceived +=
118:                 new EventHandler<AnnouncementEventArgs>(this.OnOfflineAnnouncement);
119: 
120: 
121:             // Create the service host with a singleton
122:             mAnnouncementServiceHost = new ServiceHost(mAnnouncementService);
123:             // Add the announcement endpoint
124:             mUdpAnnouncementEndpoint = new UdpAnnouncementEndpoint();
125: 
126:             mAnnouncementServiceHost.AddServiceEndpoint(mUdpAnnouncementEndpoint);
127:             // Open the host async
128:             mAnnouncementServiceHost.Open();
129:         }
130:         /// <summary>
131:         /// 
132:         /// Get a notification from a cell that its power up 
133:         /// </summary>
134:         /// <param name="sender"></param>
135:         /// <param name="e"></param>
136:         private void OnOnlineAnnouncement(object sender, AnnouncementEventArgs e)
137:         {
138: 
139:         }
140: 
141:         private void OnOfflineAnnouncement(object sender, AnnouncementEventArgs e)
142:         {
143: 
144:         }
145:     }
146: }
147: 

A standard code for the mission of searching for services and registering  for hello goodbye announcements  .
When I execute the code the CPU consumption of the application is climbing and stay high for a while.
I found out that the WCF infrastructure generate a lot of exceptions after executing the code .
 
Capture12


The visual studio debugger doesn't break in any exception so I try to figure out the exceptions source using windbg.


Using WinDBG
loading  sos :
.loadby sos clr
configure to catache the exceptions :
sxe clr


Then allot of exceptions started to  arrive:
(1298.1df8): CLR exception - code e0434352 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
KERNELBASE!RaiseException+0x54:
7579b760 c9              leave


Investigate the exceptions:
sxe 0xe0434352

0:000> !PrintException
Exception object: 01e45768
Exception type:   System.ArgumentException
Message:          The 'result' argument must be of type Message.
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    0020ECC8 519CD54D System_ServiceModel_ni!System.ServiceModel.Dispatcher.MessageOperationFormatter.SerializeReply(System.ServiceModel.Channels.MessageVersion, System.Object[], System.Object)+0x336c31
    0020ECE4 50D2907F System_ServiceModel_ni!System.ServiceModel.Dispatcher.DispatchOperationRuntime.SerializeOutputs(System.ServiceModel.Dispatcher.MessageRpc ByRef)+0x8f
    0020ED44 50D26C42 System_ServiceModel_ni!System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(System.ServiceModel.Dispatcher.MessageRpc ByRef)+0x562

0:000> !CLRStack
OS Thread Id: 0x1df8 (0)
Child SP       IP Call Site
0020ec0c 7579b760 [HelperMethodFrame: 0020ec0c]
0020ec7c 50d26cbf *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.ServiceModel\23288b62c0dc0d181c1ffc0614644b6d\System.ServiceModel.ni.dll
*** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.ServiceModel\23288b62c0dc0d181c1ffc0614644b6d\System.ServiceModel.ni.dll
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(System.ServiceModel.Dispatcher.MessageRpc ByRef)
0020eda8 50d26582 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(System.ServiceModel.Dispatcher.MessageRpc ByRef)
0020ede0 50d261eb System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(System.ServiceModel.Dispatcher.MessageRpc ByRef)
0020edf4 50d25067 System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean)
0020ee40 50d33dcd System.ServiceModel.Dispatcher.MessageRpc+Wrapper.Resume(Boolean ByRef)
0020ee60 51484d49 System.ServiceModel.Dispatcher.ThreadBehavior.ResumeProcessing(System.ServiceModel.Dispatcher.IResumeMessageRpc)
0020ee7c 51484c26 System.ServiceModel.Dispatcher.ThreadBehavior.SynchronizationContextStartCallback(System.Object)
0020ee84 646077ef *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\WindowsBase\4692c27dd31276c56a76ec0da8d3e453\WindowsBase.ni.dll
*** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\WindowsBase\4692c27dd31276c56a76ec0da8d3e453\WindowsBase.ni.dll
System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
0020eea4 6460768a MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
0020eee8 645f2d5c System.Windows.Threading.DispatcherOperation.InvokeImpl()


The cause of the exceptions is the WCF infrastructure !!!!
Configure the application  or logging the messages :


  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:     <startup> 
  4:         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  5:     </startup>
  6:   <system.serviceModel>
  7: 
  8: 
  9:     <diagnostics>
 10:       <!-- Enable Message Logging here -->
 11:       <!-- log all messages received or sent at the transport or service model levels -->
 12:       <messageLogging logEntireMessage="true" maxMessagesToLog="300" logMessagesAtServiceLevel="true" logMalformedMessages="true" logMessagesAtTransportLevel="true"/>
 13:     </diagnostics>
 14: 
 15:   </system.serviceModel>
 16: 
 17:   <system.diagnostics>
 18:     <sources>
 19:       <source name="System.ServiceModel" switchValue="Information,ActivityTracing" propagateActivity="true">
 20:         <listeners>
 21:           <add name="xml"/>
 22:         </listeners>
 23:       </source>
 24:       <source name="System.ServiceModel.MessageLogging">
 25:         <listeners>
 26:           <add name="xml"/>
 27:         </listeners>
 28:       </source>
 29:     </sources>
 30:     <sharedListeners>
 31:       <add initializeData="C:\logs\SimulatorGuiB10.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="xml"/>
 32:     </sharedListeners>
 33:     <trace autoflush="true"/>
 34:   </system.diagnostics>
 35: </configuration>


Inspect the  log :Capture13 The message with Action 'http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None). 

I understand that there  is  contract mismatch


So I checked the address of the Discovery endpoint and the Announcement endpoint


Capture14


Capture15


The contract is different between them  but the address is the same .
Resolving the problem:
Set the address manually to be different solve the problem:


  1: private void OpenAnnouncementService()
  2:         {
  3:             mAnnouncementService = new AnnouncementService();
  4:             // Add event handlers
  5: 
  6:             mAnnouncementService.OnlineAnnouncementReceived +=
  7:                 new EventHandler<AnnouncementEventArgs>(this.OnOnlineAnnouncement);
  8:             mAnnouncementService.OfflineAnnouncementReceived +=
  9:                 new EventHandler<AnnouncementEventArgs>(this.OnOfflineAnnouncement);
 10: 
 11: 
 12:             // Create the service host with a singleton
 13:             mAnnouncementServiceHost = new ServiceHost(mAnnouncementService);
 14:             // Add the announcement endpoint
 15:             mUdpAnnouncementEndpoint = new UdpAnnouncementEndpoint();
 16: 
 17:             mUdpAnnouncementEndpoint.MulticastAddress = new Uri("soap.udp://239.255.255.251:3702/");
 18: 
 19:             mAnnouncementServiceHost.AddServiceEndpoint(mUdpAnnouncementEndpoint);
 20:             // Open the host async
 21:             mAnnouncementServiceHost.Open();
 22:         }



 

אין תגובות:

הוסף רשומת תגובה