Randall Carter
Randall Carter

Reputation: 21

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

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

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.

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.

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;
        }
    }
}

Upvotes: 0

Views: 1289

Answers (1)

fejesjoco
fejesjoco

Reputation: 11903

It's because it runs in another process, another appdomain. You need some kind of IPC to make this work.

Upvotes: 0

Related Questions