Raise custom event in a Windows Service from a shared library
<p>Code below represents the shared library with its <strong><em>OnAppSettingsChanged</em></strong> event, below that the Windows Form application that subscribes to the event and handles it when raised. The custom event data is nothing more than a date. Let’s call the shared library <strong><em>MyRegistryClass</em></strong> 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 <strong><em>MySettings</em></strong> which will hold values that are read and written to the <strong><em>MyRegistryClass</em></strong> library as well as other data used by the Windows Form application.</p>

<p>All of this works fine as long as I am raising my custom event from <strong><em>MyRegistryClass</em></strong> and handling it in a Windows Form application. Now I want to share the <strong><em>MyRegistryClass</em></strong> and <strong><em>MySettings</em></strong> libraries with a Windows Service using some or all of the features in each.</p>

<p>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.</p>

<p>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? I’m stumped and could use some guidance. </p>

<pre><code>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;
        }
    }
}
</code></pre>
