I have a problem. I encoded a wcf client (WPF and C #) that uses wsHttpBinding. And I use duplex. I have a function that I call a wcf service every minute called KeepConnection. And I never close the client proxy because I need to constantly βconnectβ to the client for service callbacks. But when running this client on Windows XP, I have a strange memory problem with my application. During normal operation on win 7 / vista, the application uses only 40 MB of memory in taskmanger. Xp is constantly increasing memory usage every second. I received more than 700 mb in 2 days.
Is there a way to fix this or is it related to XP. Thanks for the help.
Service Code:
My client code.
private InstanceContext instanceContext; //Wcf instance context for callbacks. public static BootDialog _bootScreen = new BootDialog(); //Boot window. public static RetryDialog _retryScreen = new RetryDialog(); //Retry window. public static ProductionServiceClient service; //Wcf service client public static ClientCallBack clientBack; //Client callback events and handler. public static ClientTokenResponse ClientToken; //ClientToken from wcf service. public static int[] ScannerNumbers; public static IList<HighlightArticleDto> highListArticleList; //List and color of witch list to highligt. private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); private static ClientTokenRequest clientRequest; private Timer _keepAliveTimer = new Timer(); private void Application_Startup(object sender, StartupEventArgs e) { _logger.Trace("Enter Application_Startup()."); int[] scannerNumberList = ParseHandler.GetScannersFromSettingString(Settings.Default.Scanners); //Saves it globally App.ScannerNumbers = scannerNumberList; _logger.Info("Getting {0} scanners for this client.", scannerNumberList.Count()); clientBack = new ClientCallBack(); instanceContext = new InstanceContext(clientBack); //ToDO : This fix is for XP computer with the http://+:80/Temporary_Listen_Addresses/c269764e-808e-4284-ad7f-4e0eb88ee951/ error. WSDualHttpBinding binding = new WSDualHttpBinding(); binding.Name = "WsDualTcpEndpoint"; binding.CloseTimeout = new TimeSpan(0, 0, 10); binding.OpenTimeout = new TimeSpan(0, 0, 10); //binding.ReceiveTimeout = new TimeSpan(0, 0, 30); binding.SendTimeout = new TimeSpan(0, 0, 10); binding.BypassProxyOnLocal = false; binding.TransactionFlow = false; binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; binding.MaxBufferPoolSize = 524288; binding.MaxReceivedMessageSize = 65536; binding.MessageEncoding = WSMessageEncoding.Text; binding.TextEncoding = System.Text.Encoding.UTF8; binding.UseDefaultWebProxy = false; binding.Security.Mode = WSDualHttpSecurityMode.None; StringBuilder sb = new StringBuilder(); sb.Append("http://").Append(GetLocalIp()).Append(":808/WSDualOnXP"); _logger.Debug("Client base address : {1}.", sb.ToString()); binding.ClientBaseAddress = new Uri(sb.ToString()); EndpointAddress endpoint = new EndpointAddress(Settings.Default.ServerAddress); service = new ProductionServiceClient(instanceContext, binding, endpoint); //2011-08-25 Test utav clientbase //service = new ProductionServiceClient(instanceContext, "WsDualTcpEndpoint", Settings.Default.ServerAddress); _logger.Debug("Server address : {0}.", Settings.Default.ServerAddress); //ToDo Disabled GeneralDialog. //2011-05-25 Remove this comment if generaldialog wants to be seen. //if (scannerNumberList.Count() == 0 || String.IsNullOrEmpty(Settings.Default.ServerAddress)) //{ // GeneralDialog dialog = new GeneralDialog(); // dialog.Show(); // return; //} //Subscribe to wcf service. SubscribeToService(scannerNumberList); //Keep connection to the service alive. KeepAlive(); //Start timer for highlight list GetHighLightListTimer(); //Catch unhandled exceptions this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException); } private void KeepAlive() { _keepAliveTimer.Interval = 31000; _keepAliveTimer.Elapsed += ( (object o, ElapsedEventArgs args) => { try { _keepAliveTimer.Stop(); if (service.State != CommunicationState.Opened) { if (service != null) { service.Abort(); } ShowRetryDialog(); RetryToSubscribe(); } service.KeepConnection(); } catch (TimeoutException ex) { if (service != null) { service.Abort(); } ShowRetryDialog(); RetryToSubscribe(); } catch (CommunicationException ex) { if (service.State != CommunicationState.Opened) { if (service != null) { service.Abort(); } ShowRetryDialog(); RetryToSubscribe(); } } catch { if (service != null) { service.Abort(); } _keepAliveTimer.Stop(); ShowRetryDialog(); RetryToSubscribe(); } finally { _keepAliveTimer.Start(); } } ); _keepAliveTimer.Start(); }
And my client callbacks.
#region ClientCallBacks //When service callbacks to the client this methods will be triggered. void clientBack_ClientNotified(object sender, ClientNotifiedEventArgs e) { throw new NotImplementedException(); } void clientBack_RemoveFromDisplayEvent(object sender, RemoveFromDisplayEventArgs e) { try { _logger.Info("Remove from display."); userControlChairs.Dispatcher.Invoke((Action)(() => { _queueProductionItems.Remove(e.OrderResponse); })); } catch (Exception ex) { MessageBox.Show(ex.Message); } } void clientBack_AddToDisplayEvent(object sender, AddToDisplayEventArgs e) { try { _logger.Info("Add to display."); userControlChairs.Dispatcher.Invoke((Action)(() => { _queueProductionItems.Add(e.OrderResponse); })); } catch (Exception ex) { MessageBox.Show(ex.Message); } } void clientBack_UpdateQueueDisplayEvent(object sender, UpdateQueueDisplayEventArgs e) { try { _logger.Info("Update queue display."); userControlQueue.Dispatcher.Invoke((Action)(() => { _queueDisplayItems.Clear(); foreach (OrderDto o in e.UnfinishedOrdersResponse.Orders) { _queueDisplayItems.Add(o); } })); } catch (Exception ex) { MessageBox.Show(ex.Message); } } #endregion private ObservableOrderResponseQueue _queueProductionItems = new ObservableOrderResponseQueue(); //List of the chairs that will be displayed. private ObservableCollection<ErrorMessage> _errorMessages = new ObservableCollection<ErrorMessage>(); //List that holds the error message for debug private ObservableCollection<OrderDto> _queueDisplayItems = new ObservableCollection<OrderDto>();//List of order and quanities left. (DisplayQueue). private ObservableCollection<DebugInfo> _queueDebugInfo = new ObservableCollection<DebugInfo>(); //
RetryToSubsribe Method.
public void RetryToSubscribe() { try { WSDualHttpBinding binding = new WSDualHttpBinding(); binding.Name = "WsDualTcpEndpoint"; binding.CloseTimeout = new TimeSpan(0, 1, 0); binding.OpenTimeout = new TimeSpan(0, 1, 0); //binding.ReceiveTimeout = new TimeSpan(0, 0, 30); binding.SendTimeout = new TimeSpan(0, 1, 0); binding.BypassProxyOnLocal = false; binding.TransactionFlow = false; binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; binding.MaxBufferPoolSize = 524288; binding.MaxReceivedMessageSize = 65536; binding.MessageEncoding = WSMessageEncoding.Text; binding.TextEncoding = System.Text.Encoding.UTF8; binding.UseDefaultWebProxy = false; binding.Security.Mode = WSDualHttpSecurityMode.None; StringBuilder sb = new StringBuilder(); sb.Append("http://").Append(GetLocalIp()).Append(":808/WSDualOnXP"); _logger.Debug("Client base address : {1}.", sb.ToString()); binding.ClientBaseAddress = new Uri(sb.ToString()); EndpointAddress endpoint = new EndpointAddress(Settings.Default.ServerAddress); service = new ProductionServiceClient(instanceContext, binding, endpoint); ClientTokenRequest request = new ClientTokenRequest(); request.RequestId = NewRequestId; request.StationNumbers = ScannerNumbers; clientRequest = request; service.Subscribe(request); //Close the retry window. this.Dispatcher.Invoke((Action)(() => { //Set the background to default. this.MainWindow.SetResourceReference(Window.BackgroundProperty, "MainBackground"); _retryScreen.Hide(); })); } catch (Exception ex) { _logger.Error(ex.Message); } }