Click here to Skip to main content
15,894,405 members
Articles / Programming Languages / Visual Basic

Building a Class that Raises Events in a Specific or UI Thread

Rate me:
Please Sign up or sign in to vote.
4.57/5 (6 votes)
8 Mar 2013CPOL6 min read 79.6K   1.7K   35  
A BackgroundWorkerThreadSafe Class in C# and VB.Net
public class BackgroundWorkerThreadSafe : System.ComponentModel.BackgroundWorker //System.Windows.Threading.Dispatcher may require you to Add a Reference to "WindowsBase" (yes that is a Dot.Net library)
{
    public new event ProgressChangedEventHandler ProgressChanged;
    public delegate void ProgressChangedEventHandler(object sender, System.ComponentModel.ProgressChangedEventArgs e);
    public new event RunWorkerCompletedEventHandler RunWorkerCompleted;
    public delegate void RunWorkerCompletedEventHandler(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e);

    private System.Windows.Threading.Dispatcher m_ExplicitDispatcher = null;
    protected override void OnProgressChanged(System.ComponentModel.ProgressChangedEventArgs e)
    {
        RaiseEventAndExecuteItInAnExplicitOrUIThread(ProgressChanged, new object[] {
			this,
			e
		}, m_ExplicitDispatcher);
    }

    protected override void OnRunWorkerCompleted(System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
        RaiseEventAndExecuteItInAnExplicitOrUIThread(RunWorkerCompleted, new object[] {
			this,
			e
		}, m_ExplicitDispatcher);
    }

    public BackgroundWorkerThreadSafe(System.Windows.Threading.Dispatcher ExplicitDispatcher)
        : base()
    {
        m_ExplicitDispatcher = ExplicitDispatcher;
    }

    private static void RaiseEventAndExecuteItInAnExplicitOrUIThread(System.MulticastDelegate _event, object[] _ParamArray_args, System.Windows.Threading.Dispatcher ExplicitThreadSynchronizationDispatcher)
    {
        if ((_event != null))
        {
            if (_event.GetInvocationList().Length > 0)
            {
                System.ComponentModel.ISynchronizeInvoke _sync = null;
                foreach (System.MulticastDelegate _delegate in _event.GetInvocationList())
                {
                    if (((ExplicitThreadSynchronizationDispatcher == null) && (_sync == null) && (typeof(System.ComponentModel.ISynchronizeInvoke).IsAssignableFrom(_delegate.Target.GetType())) && (!_delegate.Target.GetType().IsAbstract)))
                    {
                        try
                        {
                            _sync = (System.ComponentModel.ISynchronizeInvoke)_delegate.Target;
                        }
                        catch (System.Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine(ex.ToString());
                            _sync = null;
                        }
                    }
                    if ((ExplicitThreadSynchronizationDispatcher != null))
                    {
                        try
                        {
                            ExplicitThreadSynchronizationDispatcher.Invoke(_delegate, _ParamArray_args);
                        }
                        catch (System.Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine(ex.ToString());
                        }
                    }
                    else
                    {
                        if (_sync == null)
                        {
                            try
                            {
                                _delegate.DynamicInvoke(_ParamArray_args);
                            }
                            catch (System.Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine(ex.ToString());
                            }
                        }
                        else
                        {
                            try
                            {
                                _sync.Invoke(_delegate, _ParamArray_args);
                            }
                            catch (System.Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine(ex.ToString());
                            }
                        }
                    }
                }
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions