|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.