.net - 如何将 Windows 服务与系统托盘应用程序连接
我有一个定期执行某些操作的 Windows 服务。 在用户帐户上运行系统托盘应用程序(用 C# 编写),该应用程序与 Windows 服务(通过 .net 远程处理)进行通信,并向用户显示状态和一些选项。
除了系统托盘应用程序使用 20-30MB RAM 之外,一切都运行良好! 它必须在终端环境中工作,当 50 个用户登录时,只有系统托盘应用程序占用 >1GB 的 RAM!我不必添加,这是错误的:)
是否可以编写很小的 .net 系统托盘应用程序? (最大 1-2MB?) 或者我应该用c/c++编写它?那么,Windows 服务(用 C# 编写)和 systray 应用程序之间应该使用哪种通信方式?
I have a windows service that do something periodically.
on user account runs systray application (written in C#) that communicate with windows service (thru .net remoting) and shows a status and some option to users.
Everything works well beside that systray app uses 20-30MB of RAM !
it have to work in terminal environment, when 50 users login, only systray apps take >1GB of RAM ! and i don't have to add, that's wrong :)
Is it possible to write .net systray application that will be small ? (1-2MB max?)
or should I write it in c/c++? then, what kind of communication should I use between windows service (written in C#) and systray app ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
另一个考虑因素是 .NET 应用程序消耗的大量内存位于共享 (.NET) dll 中,并且在运行多个实例时不会重复(除非操作系统使用随机 dll 加载地址)。
您还可以通过将程序集安装到 GAC 并使用
ngen
对其进行预 JIT 来减少 JIT 编译使用的内存。同样,这将导致内存使用量减少,除非操作系统随机化 dll 加载地址。Another consideration is that a lot of memory consumed by .NET apps is in shared (.NET) dlls, and will not duplicate when multiple instances are run (unless the OS uses randomized dll load addresses).
You can also reduce the memory used by JIT compiling by installing your assemblies to the GAC and pre-JITting them using
ngen
. Again, this will result in reduced memory usage unless the OS randomizes dll load addresses.我在代码中添加了以下行(应用程序有时会与 GC.Collect() 一起调用它)
,在使用后清空一些对象(绘图菜单和图标)后,内存使用量下降到约 2MB(从 15-25MB),内存使用量下降到~540KB!
它会增长一点(如果我使用上下文菜单,则增长到〜2-3MB,但随后又回落到〜540KB)
所以,目标实现了:)
I've added following line to my code (app calls it sometimes along with GC.Collect() )
Memory usage dropped to ~2MB (from 15-25MB), after nulling some objects after use (drawing menu and icon), memory usage dropped to ~540KB !
it grows a little (to ~2-3MB if I use context menu, but then it drops back to ~540KB)
So, goal achieved :)
您遇到的内存使用问题很可能是您的应用程序特有的,而不是所有使用 .NET 构建的系统托盘应用程序。
您应该分析您的应用程序以确定大量内存使用发生在哪里。
It's most likely that the memory usage issues you are experiencing are specific to your application, rather than all sys-tray apps built with .NET.
You should profile your application to determine where the large memory usage is happening.
您的系统托盘应用程序可能存在内存泄漏。一个好的分析工具可以帮助您了解正在发生的情况。
Your sys-tray application is probably having memory leaks. A good profiling tool can help you understand what's happening.
所以,如果我决定用 c/c++ 编写系统托盘应用程序
我应该在 Windows 服务(用 C# 编写)和 systray 应用程序之间使用哪种通信?
So, if i decide to write systray app in c/c++
what kind of communication should I use between windows service (written in C#) and systray app ?
我们过去遇到过类似的问题,我会与您分享我的解决方案。
.Net 框架 TCP/IP 库的性能非常低下,并且像其他任何东西一样消耗内存。
作为解决方案,我们选择来自 KODART 的 XF 库一个开源高性能 TCP /.Net 应用程序的 IP 库。它在多个客户端连接上的扩展能力令人惊讶。
您可以使用 XF 库建立 TCP/IP 通道并亲自观察结果。
查看本文了解更多信息。
We faced similar problem in past and I'd share my solution with you.
.Net framework TCP/IP library is pathetically under-performing and eats up memory like anything.
As solution to this we opted to to XF library from KODART an open-source high-performance TCP/IP library for .Net applications. It scales amazingly on multiple client connections.
You can establish TCP/IP channels using XF library and observe the results yourself.
Checkout this article for additional information.
WCF(.NET 3.0 或 3.5?)的发布使得 .NET 远程处理变得过时。使用 WCF,您可以选择在 Windows 服务中托管 WCF 服务器,然后通过 TCP/IP 与您的服务进行通信。根据我的经验,WCF 比 .NET 远程处理稳定得多。
根据您的需要,您可能需要考虑使用 < code>ServiceController 而不是远程处理或 WCF。使用
ServiceController
,您可以启动和停止服务,还可以使用Service.Controller.ExecuteCommand
。使用ServiceController
比远程处理和 WCF 简单得多,但不够灵活。The release of WCF (.NET 3.0 or 3.5?) rendered .NET remoting obsolete. With WCF you have the option of hosting a WCF server in your Windows service and then communicate with your service through TCP/IP. In my experience WCF is far more stable than .NET remoting.
Depending on your needs you may want to consider using
ServiceController
instead of remoting or WCF. WithServiceController
you can start and stop services and you can also send application defined commands (as integers) to your service usingService.Controller.ExecuteCommand
. UsingServiceController
is a lot simpler than remoting and WCF but not as flexible.如果您需要的只是更改系统托盘中的图标、更改工具提示并显示小上下文菜单,请务必使用裸 WinAPI 用 C/C++ 编写系统托盘应用程序,并使用消息模式命名管道进行通信与服务。不要忘记使用
Global\
管道名称前缀来允许在多个会话中运行的系统托盘应用程序连接到同一服务。If all you need is change icons in systray, change tooltip and show small context menu, by all means write your systray app in C/C++ using bare WinAPI, and use a message-mode named pipe to communicate with the service. Don't forget to use the
Global\
pipe name prefix to allow systray apps running in multiple sessions to connect to the same service.