.Net CF 在应用程序的生命周期内运行线程

发布于 2024-07-19 00:57:12 字数 3087 浏览 6 评论 0原文

我正在用 C# 开发一个 .Net Compact 框架应用程序,它利用设备上安装的一些第三方消息队列软件。

我对这个环境相当陌生,想知道是否可以通过一些明智的眼睛来运行架构的一些关键概念,看看我是否走在正确的轨道上,或者如何改进它。

当我的应用程序运行时,我需要保持消息队列库在后台运行,以便它可以发出通知并向我的应用程序通知任何传入消息并处理我的应用程序生成的消息。 它需要在我的应用程序的整个生命周期中运行,所以我认为最好的方法是在我的应用程序启动时在它自己的线程中运行它?

我不想用代码淹没这篇文章,所以我把我认为重要的部分放在了上面,如果我需要澄清更多,请告诉我。

当应用程序启动时,我在一个单独的线程中启动消息进程,如下所示,

[MTAThread]
static void Main()
{
    //Run the message processor in its own thread
Thread messagingThread = new Thread(new ThreadStart(msgProcessorStart));
messagingThread.Priority = ThreadPriority.Highest;
messagingThread.Start();

…..
Application.Run(splashForm);
}

private static void msgProcessorStart()
{
MessageProcessor.Start();                      
}

消息处理器是消息传递库的一个外观,用于简化交互并保留它的单个实例。 我在下面发布了其中的一部分,它会引发未送达事件并在收到消息时发出通知。

public static class MessageProcessor
    {
        #region Declarations

//private static reference to the MessageProvider as specified in the configuration files.
private static readonly IMessageProcessor _messageProcessor = MessageAccess.MessageProvider;

        #endregion

        #region Constructor

        /// <summary>
        /// Static constructor, connects to the events on the messageProcessor instance which 
        /// relate to messages received, notifications received and exceptions raised.
        /// </summary>
        static MessageProcessor()
        {
            //Connect up events specifed on the IMessageProcessor interface. 
            _messageProcessor.MessageReceived += messageReceived; 
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Sends a request based data message.
        /// </summary>
        /// <typeparam name="T">Message which implements RequestBase</typeparam>
        /// <param name="message">The message to send</param>
        public static void SendMessage<T>(T message) where T : RequestBase
        {
            _messageProcessor.SendMessage(message);
        }

        /// <summary>
        /// Starts the Message Processor. 
        /// </summary>
        /// <returns>bool, true if started successfully.</returns>
        public static void Start()
        {
            _messageProcessor.Start();
        }

        #endregion

        #region Private methods

        //Registered listener of the IMessageProcessor.MessageReceived event
        private static void messageReceived(object sender, MsgEventArgs<IMessage> message)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(processMessage),(object)message.Value);
        }


        //Invoked via messageReceived.
        private static void processMessage(object msg)
        {            
            //process the message
        }

        #endregion
    }

首先调用Start方法并建立会话; 然后我们将开始接收通知并能够发送消息。

收到消息后,我当前正在通过线程池在单独的线程中管理事件处理,以便继续并响应其他通知和消息。

这看起来是一种合理的方法吗?它是否能确保我的消息队列库能够独立于我的应用程序进行处理?

如有任何建议,我们将不胜感激,感谢您的宝贵时间。

I am developing a .Net Compact framework application in C# which utilises some third party message queuing software installed on the device.

I am fairly new to this environment and was wondering if I could run a few key concepts of the architecture past some wiser eyes to see if I am on the right track or how it could be improved.

Whilst my application is running I need to keep the message queuing library running in the background so that it can raise notifications and inform my application of any incoming messages and process messages my application generates. It needs to run throughout the lifetime of my application, so I am thinking the best way to do this is run it in its own thread when my application launches?

I didn’t want to flood this post with code so I have put the sections on I think are important, please let me know if I need to clarify more.

I start the Message Process in a separate thread when the application launches like this,

[MTAThread]
static void Main()
{
    //Run the message processor in its own thread
Thread messagingThread = new Thread(new ThreadStart(msgProcessorStart));
messagingThread.Priority = ThreadPriority.Highest;
messagingThread.Start();

…..
Application.Run(splashForm);
}

private static void msgProcessorStart()
{
MessageProcessor.Start();                      
}

The MessageProcessor is a façade over the messaging library to simplify interaction and keep a single instance of it. I have posted part of it below, it raises events for non-delivery and notifies when messages are received.

public static class MessageProcessor
    {
        #region Declarations

//private static reference to the MessageProvider as specified in the configuration files.
private static readonly IMessageProcessor _messageProcessor = MessageAccess.MessageProvider;

        #endregion

        #region Constructor

        /// <summary>
        /// Static constructor, connects to the events on the messageProcessor instance which 
        /// relate to messages received, notifications received and exceptions raised.
        /// </summary>
        static MessageProcessor()
        {
            //Connect up events specifed on the IMessageProcessor interface. 
            _messageProcessor.MessageReceived += messageReceived; 
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Sends a request based data message.
        /// </summary>
        /// <typeparam name="T">Message which implements RequestBase</typeparam>
        /// <param name="message">The message to send</param>
        public static void SendMessage<T>(T message) where T : RequestBase
        {
            _messageProcessor.SendMessage(message);
        }

        /// <summary>
        /// Starts the Message Processor. 
        /// </summary>
        /// <returns>bool, true if started successfully.</returns>
        public static void Start()
        {
            _messageProcessor.Start();
        }

        #endregion

        #region Private methods

        //Registered listener of the IMessageProcessor.MessageReceived event
        private static void messageReceived(object sender, MsgEventArgs<IMessage> message)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(processMessage),(object)message.Value);
        }


        //Invoked via messageReceived.
        private static void processMessage(object msg)
        {            
            //process the message
        }

        #endregion
    }

The Start method is first called and establishes a session; we’ll then start to received notifications and be able to send messages.

When a message is received I am currently managing event processing in a separate thread via the ThreadPool, in order to continue and respond to other notifications and messages.

Does this look a reasonable approach and will it ensure that my message queuing library will be able to process in isolation from my application?

Any advice would be gratefully received, thanks for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

GRAY°灰色天空 2024-07-26 00:57:13

从概念上讲,将其放入单独的线程中是正确的选择。

后台线程可以在以下几种情况下停止操作:

  1. 整个应用程序已关闭(收到 WM_CLOSE 消息)
  2. 抛出异常且未在后台线程上下文中捕获
  3. 操作系统由于内存限制而必须关闭整个应用程序

在代码中,您只能阻止条件数字 2。

另一方面,如果您想要完美的隔离,您可以编写一个 Windows 服务并将其安装在设备上。 但我不认为 .NET CF 服务本身可用。 然而,有一些实现可以用来克服这个障碍。

另一种方法是使用该循环和隐藏的主窗口创建单独的应用程序。

Conceptually it is right choice to put it into separate thread.

There are several conditions when background thread can stop operating:

  1. whole application has closed (received WM_CLOSE message)
  2. exception was thrown and not caught in the background thread context
  3. operating system has to shutdown whole application because of memory constraints

In your code you can only prevent condition number 2.

On the other hand if you want perfect isolation you can write a windows service and install it on the device. But I do not think there are .NET CF services natively available. There are however some implementations out there that can be used to overcome this obstacle.

Another way is to have separate application with that loop and hidden main window.

挽清梦 2024-07-26 00:57:13

看起来完全合理。 由于我通常使用 DI 框架,所以在实现上我的做法有点不同,但概念是相同的。 我要添加的一件事是将线程的 IsBackground 属性设置为 true

Seems perfectly reasonable. I've have done it a bit differently in implementation since I typically use a DI framework, but the concept would have been the same. One thing I would add is to set the IsBackground property of the thread to true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文