0

I'm trying to implement my own basic BackgroundWorker, since the Compact Framework doesn't provide one, is it advisable to invoke the WorkCompletedHandler on the UI thread like this?

CustomBackgroundWorker Class:

public delegate void DoWorkHandler(object sender, DoWorkArgs e);
public delegate void WorkCompletedHandler(object sender, WorkCompletedArgs e);
class CustomBackgroundWorker
    {
        private System.Windows.Forms.Control _owning_control;
        private System.Threading.Thread _t;
        private Exception _e = null;
        public event DoWorkHandler DoWork;
        public event WorkCompletedHandler WorkCompleted;

        public CustomBackgroundWorker(System.Windows.Forms.Control Owning_Control)
        {
            if (Owning_Control == null) throw new ArgumentNullException("Owning_Control");
            _owning_control = Owning_Control;
        }
        public void RunWorkerAsync()
        {
            this.RunWorkerAsync(null);
        }
        public void RunWorkerAsync(object Parameter)
        {
            if (DoWork == null) throw new Exception("DoWork Event isn't subscribed.");
            DoWorkArgs dowork_args = new DoWorkArgs(Parameter);
            _t = new Thread(() =>
                {
                    try
                    {
                        DoWork(this, dowork_args);
                    }
                    catch (Exception ex)
                    {
                        _e = ex;
                    }
                    if (WorkCompleted != null)
                    {
                        _owning_control.BeginInvoke(new Action(() =>
                            {
                                WorkCompleted(this, new WorkCompletedArgs(_e, dowork_args.Result));
                            }));
                    }
                });
            _t.Name = "BackgroundWorker Thread";
            _t.Start();
        }
    }

    public class DoWorkArgs
    {
        public object Result { get; set; }
        public object Parameter { get; private set; }
        public DoWorkArgs(object Parameter)
        {
            this.Parameter = Parameter;
        }
    }

    public class WorkCompletedArgs
    {
        private object _result;
        public WorkCompletedArgs(Exception Error, object Result)
        {
            this.Error = Error;
            _result = Result;
        }
        public object Result
        {
            get
            {
                if (this.Error != null) throw new Exception("Can't access Result, during execution an Exception was thrown.");
                return _result;
            }
        }
        public object Error { get; private set; }
    }

A sample usage:

Thread.CurrentThread.Name = "UI Thread!";
CustomBackgroundWorker bgw = new CustomBackgroundWorker(this);
bgw.DoWork += new DoWorkHandler((o, args) =>
        {
            Debug.WriteLine("Thread: " + Thread.CurrentThread.Name);
            for (int i = 0; i < 10; i++)
                {
                    Debug.WriteLine("Tick: " + i.ToString());
                    Thread.Sleep(1000);
                    args.Result = i;
                }
            });
 bgw.WorkCompleted += new WorkCompletedHandler((o, args) =>
        {
            Debug.WriteLine("Thread: " + Thread.CurrentThread.Name);
            if (args.Error == null)
            {
                Debug.WriteLine("Result: " + args.Result.ToString());
            }
        });
bgw.RunWorkerAsync();
stuartd
  • 70,509
  • 14
  • 132
  • 163
Tea With Cookies
  • 950
  • 6
  • 18
  • 1
    It may or may not be useful, but be aware that [the actual source](http://referencesource.microsoft.com/#System/compmod/system/componentmodel/BackgroundWorker.cs,85d60b0d93a826fa) for `BackgroundWorker` is available to inspect. – James Thorpe Apr 28 '15 at 10:30
  • How do you plan to notify the parent when the backgroundworker completes? I wish microsoft would include in these examples the main() method that calls the async methods. – jdweng Apr 28 '15 at 10:41
  • @JamesThorpe That was interesting to read, but I don't think the AsyncOperation class is supported in the CF. Other than that it seems the actual BackgroundWorker is implemented similarly to what i posted. – Tea With Cookies Apr 28 '15 at 10:52

0 Answers0