Click here to Skip to main content
15,896,496 members
Articles / Programming Languages / C#

Context Delegate

Rate me:
Please Sign up or sign in to vote.
4.96/5 (10 votes)
11 Jan 2008CPOL6 min read 42K   515   33  
This is an abstraction that facilitates (but is not limited to) building multi-threaded WinForms UIs.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading; 
using CodeGems.Utils;

namespace CtxDelegateSample
{
    public partial class Form1 : System.Windows.Forms.Form
    {
        private UpdateService _service;

        private delegate void ProcessUpdateDelegate(object data);

        public Form1()
        {
            // setup controls
            InitializeComponent();

            // Name the UI thread
            Thread.CurrentThread.Name = "UIThread";

            // Create an Updater service object
            _service = new UpdateService();

            // Invoke its capabilities using a normal .Net delegate.
            // UI code delegate all marshaling complexity to service level abstractions
            _service.Start(DisplayUpdate, 100, 1000);
        }

        // update listbox control with data from multithreaded service
        private void DisplayUpdate(object data)
        {
            if (data is string)
            {
                listBox1.Items.Add(Thread.CurrentThread.Name + " received " + data);
            }
        }

        /// <summary>
        /// Trivial class representing a service of some kind.
        /// </summary>
        /// <remarks>
        /// In this case the service will simply perform a specified number of callbacks to a
        /// given delegate as a given rate.
        /// 
        /// Note that the public contract for this class is bereft of any explicit reference to threading,
        /// marshaling, or contexts.  The design of ContextDelegate is intended to encourage creation of 
        /// such simple service level object contracts.
        /// 
        /// Normally, service level abstractions such as this would typically be in a separate library
        /// and would be used across a suite of domain-specific applications.
        /// </remarks>
        class UpdateService
        {
            public void Start(ProcessUpdateDelegate callback, int period, int updates)
            {
                // Convert the specified delegate to a context delegate equivalent in order
                // to transparently support possible UI callers.
                callback= ContextDelegate.Create(callback) as ProcessUpdateDelegate;

                // Define the work to be performed.
                ThreadStart work = delegate
                {
                    for (int i = 0; i < updates; ++i)
                    {
                        callback(String.Format("update {0,4} from {1}", i + 1, Thread.CurrentThread.Name));

                        Thread.Sleep(period);
                    }
                };

                // Initialize a background thread with the work to be performed, and start it.
                _thread = new Thread(work);
                _thread.Name = "UpdateThread";
                _thread.IsBackground = true;
                _thread.Start();
            }

            Thread _thread;
        }
    }
}

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