External/Aga.Controls/Threading/AbortableThreadPool.cs
author StephaneLenclud
Thu, 18 Apr 2013 23:25:10 +0200
branchMiniDisplay
changeset 444 9b09e2ee0968
permissions -rw-r--r--
Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
     1 // Stephen Toub
     2 // stoub@microsoft.com
     3 
     4 using System;
     5 using System.Collections.Generic;
     6 using System.Text;
     7 using System.Threading;
     8 
     9 namespace Aga.Controls.Threading
    10 {
    11 	public class AbortableThreadPool
    12 	{
    13 		private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
    14 		private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
    15 
    16 		public WorkItem QueueUserWorkItem(WaitCallback callback)
    17 		{
    18 			return QueueUserWorkItem(callback, null);
    19 		}
    20 
    21 		public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
    22 		{
    23 			if (callback == null) throw new ArgumentNullException("callback");
    24 
    25 			WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
    26 			lock (_callbacks)
    27 			{
    28 				_callbacks.AddLast(item);
    29 			}
    30 			ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
    31 			return item;
    32 		}
    33 
    34 		private void HandleItem(object ignored)
    35 		{
    36 			WorkItem item = null;
    37 			try
    38 			{
    39 				lock (_callbacks)
    40 				{
    41 					if (_callbacks.Count > 0)
    42 					{
    43 						item = _callbacks.First.Value;
    44 						_callbacks.RemoveFirst();
    45 					}
    46 					if (item == null)
    47 						return;
    48 					_threads.Add(item, Thread.CurrentThread);
    49 
    50 				}
    51 				ExecutionContext.Run(item.Context,
    52 					delegate { item.Callback(item.State); }, null);
    53 			}
    54 			finally
    55 			{
    56 				lock (_callbacks)
    57 				{
    58 					if (item != null)
    59 						_threads.Remove(item);
    60 				}
    61 			}
    62 		}
    63 
    64 		public bool IsMyThread(Thread thread)
    65 		{
    66 			lock (_callbacks)
    67 			{
    68 				foreach (Thread t in _threads.Values)
    69 				{
    70 					if (t == thread)
    71 						return true;
    72 				}
    73 				return false;
    74 			}
    75 		}
    76 
    77 		public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
    78 		{
    79 			if (item == null)
    80 				throw new ArgumentNullException("item");
    81 			lock (_callbacks)
    82 			{
    83 				LinkedListNode<WorkItem> node = _callbacks.Find(item);
    84 				if (node != null)
    85 				{
    86 					_callbacks.Remove(node);
    87 					return WorkItemStatus.Queued;
    88 				}
    89 				else if (_threads.ContainsKey(item))
    90 				{
    91 					if (allowAbort)
    92 					{
    93 						_threads[item].Abort();
    94 						_threads.Remove(item);
    95 						return WorkItemStatus.Aborted;
    96 					}
    97 					else
    98 						return WorkItemStatus.Executing;
    99 				}
   100 				else
   101 					return WorkItemStatus.Completed;
   102 			}
   103 		}
   104 
   105 		public void CancelAll(bool allowAbort)
   106 		{
   107 			lock (_callbacks)
   108 			{
   109 				_callbacks.Clear();
   110 				if (allowAbort)
   111 				{
   112 					foreach (Thread t in _threads.Values)
   113 						t.Abort();
   114 				}
   115 			}
   116 		}
   117 	}
   118 }