简体   繁体   English

从共享库引发Windows服务中的自定义事件

[英]Raise custom event in a Windows Service from a shared library

Code below represents the shared library with its OnAppSettingsChanged event, below that the Windows Form application that subscribes to the event and handles it when raised. 下面的代码代表共享库及其OnAppSettingsChanged事件,在该事件下方,订阅该事件并在引发事件时进行处理的Windows Form应用程序。 The custom event data is nothing more than a date. 自定义事件数据仅是日期。 Let's call the shared library MyRegistryClass it reads and writes entries to the registry and is built as a singleton instance, the same design approach is used for a class we will call MySettings which will hold values that are read and written to the MyRegistryClass library as well as other data used by the Windows Form application. 让我们将共享库MyRegistryClass称为它读取注册表并将条目写入注册表,并作为单例实例构建的方法,该类也使用相同的设计方法,我们将调用MySettings该类还将保存读取和写入MyRegistryClass库的值作为Windows窗体应用程序使用的其他数据。

All of this works fine as long as I am raising my custom event from MyRegistryClass and handling it in a Windows Form application. 只要我从MyRegistryClass引发自定义事件并在Windows Form应用程序中处理它,所有这些工作都很好。 Now I want to share the MyRegistryClass and MySettings libraries with a Windows Service using some or all of the features in each. 现在,我想使用每个服务中的某些或全部功能,与Windows服务共享MyRegistryClassMySettings库。

The problem I am running into is that the same design approach used to add an event handler to the Windows Service does not result in the service getting notification that an event has been raised, even though the Windows Form application does receive notification. 我遇到的问题是,即使Windows窗体应用程序确实收到了通知,用于向Windows服务添加事件处理程序的相同设计方法也不会导致服务收到已引发事件的通知。

I'm not finding a reason for this difference or a way to work around it, if one exists. 我没有找到这种差异的原因,也没有找到解决该差异的方法(如果存在)。 Is it because the Windows Service runs a background process or because it does not have a message loop? 是因为Windows服务运行后台进程还是因为它没有消息循环? I'm stumped and could use some guidance. 我很困惑,可以使用一些指导。

namespace CommonLibrary
{
    public delegate void AppSettingsEventHandler(object sender, 
      DateChangeEventArgs e);

    public sealed class MyRegistryClass
    {
        public event AppSettingsEventHandler OnAppSettingsChanged;
        private static MyRegistryClass instance;
        private static object synchRoot = new Object();

        public static MyRegistryClass Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (synchRoot)
                    {
                        if (instance == null)
                            instance = new MyRegistryClass();
                    }
                }
                return instance;
            }
        }

        private MyRegistryClass()
        {
           // do some work to initialize single instance class
        }

        private void RaiseAppSettingsEvent(DateTime newDate)
        {
            OnAppSettingsChanged(this, new DateChangeEventArgs(newDate));
        }

        public void SaveAppSettings(MySettings fileSettings)
        {
            // Save some Registry settings then raise the event
            RaiseAppSettingsEvent(newDateTime);
        }
   }

   public class DateChangeEventArgs : EventArgs
   {
       public DateTime NewDate { get; private set; }

       public DateChangeEventArgs(DateTime newDate)
       {
           this.NewDate = newDate;
       }
   }
}


namespace MyApplication
{
    public partial class FileCopyTrayApp : Form
    {
        private MyRegistryClass myRegistryLib;
        private MySettings mySettingsLib;

        public FileCopyTrayApp()
        {
            this.myRegistryLib = MyRegistryClass.Instance;
            this. mySettingsLib = MySettings.Instance;
            this.myRegistryLib.OnAppSettingsChanged += new 
              AppSettingsEventHandler(myRegistryLib_OnAppSettingsChanged);

        }

        private void myRegistryLib_OnAppSettingsChanged(object sender,
            DateChangeEventArgs e)
        {
            this.mySettingsLib.NextRunDateTime = e.NewDate;
        }
    }
}

It's because it runs in another process, another appdomain. 这是因为它在另一个进程(另一个应用程序域)中运行。 You need some kind of IPC to make this work. 您需要某种IPC才能完成这项工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM