External/Aga.Controls/Threading/AbortableThreadPool.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
moel@345
     1
// Stephen Toub
moel@345
     2
// stoub@microsoft.com
moel@345
     3
moel@345
     4
using System;
moel@345
     5
using System.Collections.Generic;
moel@345
     6
using System.Text;
moel@345
     7
using System.Threading;
moel@345
     8
moel@345
     9
namespace Aga.Controls.Threading
moel@345
    10
{
moel@345
    11
	public class AbortableThreadPool
moel@345
    12
	{
moel@345
    13
		private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
moel@345
    14
		private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
moel@345
    15
moel@345
    16
		public WorkItem QueueUserWorkItem(WaitCallback callback)
moel@345
    17
		{
moel@345
    18
			return QueueUserWorkItem(callback, null);
moel@345
    19
		}
moel@345
    20
moel@345
    21
		public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
moel@345
    22
		{
moel@345
    23
			if (callback == null) throw new ArgumentNullException("callback");
moel@345
    24
moel@345
    25
			WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
moel@345
    26
			lock (_callbacks)
moel@345
    27
			{
moel@345
    28
				_callbacks.AddLast(item);
moel@345
    29
			}
moel@345
    30
			ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
moel@345
    31
			return item;
moel@345
    32
		}
moel@345
    33
moel@345
    34
		private void HandleItem(object ignored)
moel@345
    35
		{
moel@345
    36
			WorkItem item = null;
moel@345
    37
			try
moel@345
    38
			{
moel@345
    39
				lock (_callbacks)
moel@345
    40
				{
moel@345
    41
					if (_callbacks.Count > 0)
moel@345
    42
					{
moel@345
    43
						item = _callbacks.First.Value;
moel@345
    44
						_callbacks.RemoveFirst();
moel@345
    45
					}
moel@345
    46
					if (item == null)
moel@345
    47
						return;
moel@345
    48
					_threads.Add(item, Thread.CurrentThread);
moel@345
    49
moel@345
    50
				}
moel@345
    51
				ExecutionContext.Run(item.Context,
moel@345
    52
					delegate { item.Callback(item.State); }, null);
moel@345
    53
			}
moel@345
    54
			finally
moel@345
    55
			{
moel@345
    56
				lock (_callbacks)
moel@345
    57
				{
moel@345
    58
					if (item != null)
moel@345
    59
						_threads.Remove(item);
moel@345
    60
				}
moel@345
    61
			}
moel@345
    62
		}
moel@345
    63
moel@345
    64
		public bool IsMyThread(Thread thread)
moel@345
    65
		{
moel@345
    66
			lock (_callbacks)
moel@345
    67
			{
moel@345
    68
				foreach (Thread t in _threads.Values)
moel@345
    69
				{
moel@345
    70
					if (t == thread)
moel@345
    71
						return true;
moel@345
    72
				}
moel@345
    73
				return false;
moel@345
    74
			}
moel@345
    75
		}
moel@345
    76
moel@345
    77
		public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
moel@345
    78
		{
moel@345
    79
			if (item == null)
moel@345
    80
				throw new ArgumentNullException("item");
moel@345
    81
			lock (_callbacks)
moel@345
    82
			{
moel@345
    83
				LinkedListNode<WorkItem> node = _callbacks.Find(item);
moel@345
    84
				if (node != null)
moel@345
    85
				{
moel@345
    86
					_callbacks.Remove(node);
moel@345
    87
					return WorkItemStatus.Queued;
moel@345
    88
				}
moel@345
    89
				else if (_threads.ContainsKey(item))
moel@345
    90
				{
moel@345
    91
					if (allowAbort)
moel@345
    92
					{
moel@345
    93
						_threads[item].Abort();
moel@345
    94
						_threads.Remove(item);
moel@345
    95
						return WorkItemStatus.Aborted;
moel@345
    96
					}
moel@345
    97
					else
moel@345
    98
						return WorkItemStatus.Executing;
moel@345
    99
				}
moel@345
   100
				else
moel@345
   101
					return WorkItemStatus.Completed;
moel@345
   102
			}
moel@345
   103
		}
moel@345
   104
moel@345
   105
		public void CancelAll(bool allowAbort)
moel@345
   106
		{
moel@345
   107
			lock (_callbacks)
moel@345
   108
			{
moel@345
   109
				_callbacks.Clear();
moel@345
   110
				if (allowAbort)
moel@345
   111
				{
moel@345
   112
					foreach (Thread t in _threads.Values)
moel@345
   113
						t.Abort();
moel@345
   114
				}
moel@345
   115
			}
moel@345
   116
		}
moel@345
   117
	}
moel@345
   118
}