Search code examples
c#multithreadingsingletonbackgroundworker

Should I put a BackgroundWorker inside a Singleton?


I have an application that takes a Wireshark capture file and feeds it (all the containing packets) into a network adapter.

Currently my application is a big mess - countless global variables & every task opened within a seperate BackgroundWorker instance etc...

To clarify - the purpose of using BackgroundWorkers here (more specifically the DoWork, RunWorkerCompleted events and the WorkerReportsProgress property) is to prevent the packet feeding operations from freezing my UI. To stop an operation, I need access to these workes - for now, global variables are used to achieve this.

So the question is - should I place my BackgroundWorker objects inside a Singleton-type class and then call this object when necessary?


Solution

  • From a technical point of view is possible, after all the singleton pattern is a design pattern that restricts the instantiation of a class to one object you can try something like this

      public class  BackWorkerSingleton
    {
        private BackgroundWorker _backgroundWorker; 
        private static  readonly  object myLock = new object();
        private static  BackWorkerSingleton  _backWorkerSingleton =  new BackWorkerSingleton();
    
        public delegate  void  ReportProgressEventHandler(object sender,MyEventsArgs e);
    
        public event ReportProgressEventHandler ReportProgress = delegate{ };  
    
        private BackWorkerSingleton()
        {
            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.DoWork += new DoWorkEventHandler(_backgroundWorker_DoWork);
            _backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
    
        }
    
        void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.ReportProgress( this, new MyEventsArgs(){Progress = e.ProgressPercentage});
        }
    
        void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // do your work here 
        }
        public void StartTheJob()
        {
            _backgroundWorker.RunWorkerAsync();
        }
        public static  BackWorkerSingleton Worker
        {
            get
            {
                lock (myLock)
                {
                    if (_backWorkerSingleton == null)
                    {
                        _backWorkerSingleton = new BackWorkerSingleton();
                    }
                }
                return _backWorkerSingleton;  
            }
        }
    
    
    }
    
    class MyEventsArgs:EventArgs
    {
        public int Progress { get; set;  }
    }
    

    and here the report progress

     private void Form1_Load(object sender, EventArgs e)
            {
                BackWorkerSingleton.Worker.ReportProgress += new BackWorkerSingleton.ReportProgressEventHandler(Worker_ReportProgress);
            }
    
            void Worker_ReportProgress(object sender, MyEventsArgs e)
            {
    
            }
    

    and call it like this

    BackWorkerSingleton.Worker.StartJob()