C# WCF 客户端 XP 上的内存泄漏

2023-12-25

我有个问题。我编写了一个使用 wsHttpBinding 的 wcf 客户端(WPF 和 c#)。 我正在使用双面打印。我有一个每分钟调用 wcf 服务的函数,称为 KeepConnection。 而且我从不关闭客户端代理,因为我需要让客户端始终“在线”以进行服务回调。但是,当在 Windows XP 上运行此客户端时,我的应用程序内存出现了一个奇怪的问题。在 win 7 /vista 上正常运行时,该应用程序在任务管理器中仅使用 40mb 内存。在Xp中,内存的使用量每秒都在不断增加。 我在 2 天内获得了超过 700mb 的数据。

有没有办法解决这个问题或者与XP有关。感谢帮助。

服务代码:

    /// <summary>
    /// Just an empty method for client to keep the connection alive with the service.
    /// </summary>
    public void KeepConnection()
    {
        _logger.Debug("Keep alive requested.");
    }

我的客户代码。

    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();
    }

和我的客户端回调。

    #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>(); //

重试订阅方法。

        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);
        }

    }

如果您可以运行 Windbg 并继续操作,您可能会发现到底泄漏了什么。

  • 在你的winxp机器上打开windbg并附加到客户端进程(让它运行一段时间以放大问题,即内存泄漏)

  • 在提示符下输入

If using .NET 2/3.5
.loadby sos mscorwks
If using .NET 4 
.loadby sos clr
  • 然后运行

!dumpheap -stat

您将获得内存中按类分组的所有对象的列表。寻找实例数最多的实例。希望这能让您知道什么是有问题的代码。

其他选项是:

!dumpheap -stat -类型 我的课*

这将只显示以 MyClass 开头的类的实例。

在与进程分离之前不要关闭 Windbg,否则它会杀死您的进程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# WCF 客户端 XP 上的内存泄漏 的相关文章

随机推荐

  • 如何加载实体框架预编译视图

    我发现我可以通过使用预编译视图来提高应用程序的性能EdmGen exe tool 这一切都很好 但我和我的大学都无法解决这个问题how生成的 cs文件实际被项目使用 似乎没有任何对任何地方生成的类的引用 那么它是如何被包含在内的呢 任何人都
  • Spring Cloud Stream 多个函数定义

    是否有可能使用函数式 spring cloud function 具有多个独立函数 绑定的样式 我发现的所有示例始终只注册一个具有默认绑定的功能 beaninput output 我想注册多个 每个都有自己的绑定 传统上这可以使用sprin
  • 领域数据库解密失败

    Question 当我尝试打开加密领域文件时Realm Browser Windows 它给了我以下消息 这不是 Realm 文件或者已加密 输入 128 个字符的十六进制编码的加密密钥 重要的 我在保存到磁盘之前关闭我的领域 Code R
  • system()的返回码 = 256

    我使用 system 在 Swift 中执行 shell 命令 正如文档中所述 如果成功 返回值应为 0 如果失败 则返回值应为 1 但我得到 256 并且执行似乎成功了 还有一些其他与魔法值 256 相关的问题 但语言不同 没有解决方案
  • 如何从 NodeJS/Tedious 连接到 SQL Azure?

    我有一个 SQL Azure 数据库 正在尝试从 Azure Linux VM 中运行的 NodeJS 应用程序连接到该数据库 当我在本地 SQL 数据库 和 NodeJS 本地计算机上时 一切工作正常 但是 当我从虚拟机运行时 我得到以下
  • Java 中的弯曲文本

    我正在寻找最简单的方法来绘制一些 我的应用程序上椭圆对象周围的文本 我需要创造一种 拥抱 的感觉 到目前为止 我已经使用 Graphics2D 类来打印我的绘图 在屏幕上 我的 画布 是 BufferedImage 我的椭圆的宽度和高度分别
  • Microsoft.IdentityModel 与 System.IdentityModel

    我正在使用表单身份验证和 ASP NET MVC 2 开发基于声明的授权系统 我看到一个命名空间 Microsoft IdentityModel 提供了许多与另一个 System IdentityModel 相同的内容 系统 身份模型 ht
  • boost测试库:多重定义错误

    我正在尝试在 Windows 版 QTCreator 中测试我已经完成的库 微积分 我创建了一个主文件 并在一个单独的文件中创建了一个类用于测试 如果我编译在中找到的示例http www boost org doc libs 1 47 0
  • .Net RIA 服务:DomainService 需要无参数构造函数?

    我在带有一些 Silverlight 组件的 ASP Net 应用程序中使用 Net RIA 服务的 7 月 CTP 我正在从 Silverlight 调用 RIA 服务 当我尝试在域服务 LinqToEntitiesDomainServi
  • Python - “导入”或将模块作为参数传递?

    我想知道是否将模块对象传递给需要它的类或对象而不是使用import可能不是一个坏主意 因为它避免了对这些模块的硬依赖 我想知道是否有人比我更了解 Python Zen 可以解释为什么这是一个可怕 不可怕的想法 你所说的这个叫做依赖注入 ht
  • 如何从常规网站调用 Chrome 扩展程序中定义的函数?

    我想创建一个不属于 chrome 插件的网站 而只是使用该插件公开的一些 API 这可能吗 如果可以 我该怎么做 我用谷歌搜索了这个问题 但找不到任何东西 我正在尝试使用内容脚本 但没有任何反应 有人可以解释这里出了什么问题吗 清单 jso
  • NodeJS Express 和 Apache 在同一服务器上

    我有一个 VPS 在 Apache 配置 etc apache2 sites available 000 default conf 中指定了多个虚拟主机 Example config
  • 如何将 Visual Studio 设置为在按下 F5 时始终生成和调试? [复制]

    这个问题在这里已经有答案了 It used to do this but now if I don t build the solution first before pressing F5 it uses the last built p
  • 替换命令后的 SED 字符(“s”)

    我知道关于s 输入命令sed 但是从未见过使用s 有人能解释一下这到底是做什么的吗 sed e s SRC DIR SRC DIR PROJECT SRC DIR g i proj cfg 我明白那个 e定义一个要执行的脚本 该脚本位于 但
  • 使用 html 标签事件更改缩放

    我是 GMaps API 和 javascript 的初学者 所以这对于真正的专家来说应该是一个简单的问题 我已经开始 玩弄 API 并想尝试一个简单的事情 但我做不到 我四处寻找答案 但没有得到 我已经创建了地图
  • 使用 ThemeData.dark() 或 ThemeData.light() 时更改 Flutter 中的字体系列

    我正在尝试设置我的字体MaterialApp 由于我使用的是深色主题 所以我想使用copyWith然后更改fontFamily 然而 copyWith没有更改的选项fontFamily MaterialApp theme ThemeData
  • 如何将触摸事件传递到tableview下的另一个视图?

    我有一个场景 我重叠了一个视图 pageViewController在视图内 与uitableview偏移量为 130 并且uitableview是透明的 只有单元格会滚动并且可见 我的要求是在 130 这个偏移量范围内 我想将触摸事件传递
  • cv2.CalibrateCamera中retval返回值的含义

    正如标题所示 我的问题是关于 OpenCv 的 calibrateCamera 函数给出的返回值 http docs opencv org modules calib3d doc camera calibration and 3d reco
  • RStudio Shiny 中绘图的比例和大小

    相关 但只谈论一般分配的绘图空间 而不是如何直接设置绘图图像大小和then缩放它以填充所需的空间 闪亮图表空间分配 https stackoverflow com questions 17204735 shiny chart space a
  • C# WCF 客户端 XP 上的内存泄漏

    我有个问题 我编写了一个使用 wsHttpBinding 的 wcf 客户端 WPF 和 c 我正在使用双面打印 我有一个每分钟调用 wcf 服务的函数 称为 KeepConnection 而且我从不关闭客户端代理 因为我需要让客户端始终