【问题标题】:.net - how to connect windows service with systray application.net - 如何将 Windows 服务与系统托盘应用程序连接起来
【发布时间】:2010-05-20 11:46:55
【问题描述】:

我有一个定期执行某些操作的 Windows 服务。 在用户帐户上运行与 Windows 服务(通过 .net 远程处理)通信的系统托盘应用程序(用 C# 编写)并向用户显示状态和一些选项。

除了系统托盘应用程序使用 20-30MB 内存之外,一切都运行良好! 它必须在终端环境下工作,当 50 个用户登录时,只有系统托盘应用程序占用 >1GB 的 RAM!而且我不必添加,这是错误的:)

是否可以编写很小的 .net 系统托盘应用程序? (最大 1-2MB?) 还是我应该用 c/c++ 编写它?那么,windows服务(用C#编写)和系统托盘应用程序之间应该使用什么样的通信呢?

【问题讨论】:

    标签: c# .net windows service systray


    【解决方案1】:

    另一个考虑因素是 .NET 应用程序消耗的大量内存位于共享 (.NET) dll 中,并且在运行多个实例时不会重复(除非操作系统使用随机的 dll 加载地址)。

    您还可以通过将程序集安装到 GAC 并使用 ngen 对它们进行预 JIT 来减少 JIT 编译使用的内存。同样,这将导致内存使用减少除非操作系统随机化 dll 加载地址。

    【讨论】:

    • 应用程序仅引用 System.* 库。应用程序仅由一个类和几个小图标组成。它更改系统托盘中的图标,更改工具提示并显示小的上下文菜单。在我的计算机(vista)上,进程资源管理器告诉我“地址空间负载随机化:已启用”这个功能有用吗?还是只占用操作系统更多的内存?
    • ASLR 从安全角度来看很有用,但会影响内存使用。
    • 我很确定 ASLR 对于 .NET ngen-ed 图像是关闭的。 Editbin.exe /dynamicbase 如果你真的想确定的话。
    • 他们 turned it on 从 .NET 3.5 SP1 开始,我刚刚使用 dumpbin my.exe /headers 检查了一个 .NET 4 项目。它已打开(“动态基础”显示在“DLL 特征”下)。
    • 那么,如果我决定用 c/c++ 编写系统托盘应用程序,我应该在 Windows 服务(用 C# 编写)和系统托盘应用程序之间使用什么样的通信?
    【解决方案2】:

    我在我的代码中添加了以下行(应用程序有时会与 GC.Collect() 一起调用它)

    System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet =
                    System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet;
    

    内存使用量下降到~2MB(从15-25MB),在使用后将一些对象(绘图菜单和图标)归零后,内存使用量下降到~540KB! 它会增长一点(如果我使用上下文菜单,会增长到 ~2-3MB,但随后会下降到 ~540KB)

    所以,目标实现了:)

    【讨论】:

      【解决方案3】:

      您遇到的内存使用问题很可能是特定于您的应用程序,而不是所有使用 .NET 构建的系统托盘应用程序。

      您应该分析您的应用程序以确定大内存使用的位置。

      【讨论】:

        【解决方案4】:

        您的系统托盘应用程序可能存在内存泄漏。一个好的分析工具可以帮助您了解正在发生的事情。

        【讨论】:

        • 没有内存泄漏(内存占用不会增加)。这是一个完全简单的应用程序 - 只显示上下文菜单:i50.tinypic.com/sxku0x.jpg 并且它需要大约 13MB 的 RAM,所以我假设我无法在 .net 中创建小型 (
        【解决方案5】:

        所以,如果我决定用 c/c++ 编写系统托盘应用程序 我应该在 windows 服务(用 C# 编写)和 systray 应用程序之间使用什么样的通信?

        【讨论】:

          【解决方案6】:

          我们过去遇到过类似的问题,我会与您分享我的解决方案。

          .Net 框架 TCP/IP 库的性能非常糟糕,而且会像其他任何东西一样占用内存。

          作为解决方案,我们选择了XF library from KODART 一个用于 .Net 应用程序的开源高性能 TCP/IP 库。它可以在多个客户端连接上惊人地扩展。

          您可以使用 XF 库建立 TCP/IP 通道并自己观察结果。

          结帐this article 了解更多信息。

          【讨论】:

            【解决方案7】:

            WCF(.NET 3.0 还是 3.5?)的发布使 .NET 远程处理过时了。使用 WCF,您可以选择在 Windows 服务中托管 WCF 服务器,然后通过 TCP/IP 与您的服务进行通信。根据我的经验,WCF 比 .NET 远程处理稳定得多。

            根据您的需要,您可能需要考虑使用ServiceController 而不是远程处理或 WCF。使用ServiceController,您可以启动和停止服务,还可以使用Service.Controller.ExecuteCommand 将应用程序定义的命令(作为整数)发送到您的服务。使用ServiceController 比远程处理和 WCF 简单得多,但没有那么灵活。

            【讨论】:

              【解决方案8】:

              如果您只需要更改系统托盘中的图标、更改工具提示并显示小上下文菜单,请务必使用裸 WinAPI 以 C/C++ 编写您的系统托盘应用程序,并使用名为管道与服务通信。不要忘记使用Global\ 管道名称前缀来允许在多个会话中运行的系统托盘应用程序连接到同一个服务。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2017-10-24
                • 1970-01-01
                • 2011-07-20
                • 2012-11-18
                • 1970-01-01
                • 2010-12-09
                • 1970-01-01
                相关资源
                最近更新 更多