1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/External/Aga.Controls/Threading/AbortableThreadPool.cs Sun May 27 15:16:19 2012 +0000
1.3 @@ -0,0 +1,118 @@
1.4 +// Stephen Toub
1.5 +// stoub@microsoft.com
1.6 +
1.7 +using System;
1.8 +using System.Collections.Generic;
1.9 +using System.Text;
1.10 +using System.Threading;
1.11 +
1.12 +namespace Aga.Controls.Threading
1.13 +{
1.14 + public class AbortableThreadPool
1.15 + {
1.16 + private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
1.17 + private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
1.18 +
1.19 + public WorkItem QueueUserWorkItem(WaitCallback callback)
1.20 + {
1.21 + return QueueUserWorkItem(callback, null);
1.22 + }
1.23 +
1.24 + public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
1.25 + {
1.26 + if (callback == null) throw new ArgumentNullException("callback");
1.27 +
1.28 + WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
1.29 + lock (_callbacks)
1.30 + {
1.31 + _callbacks.AddLast(item);
1.32 + }
1.33 + ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
1.34 + return item;
1.35 + }
1.36 +
1.37 + private void HandleItem(object ignored)
1.38 + {
1.39 + WorkItem item = null;
1.40 + try
1.41 + {
1.42 + lock (_callbacks)
1.43 + {
1.44 + if (_callbacks.Count > 0)
1.45 + {
1.46 + item = _callbacks.First.Value;
1.47 + _callbacks.RemoveFirst();
1.48 + }
1.49 + if (item == null)
1.50 + return;
1.51 + _threads.Add(item, Thread.CurrentThread);
1.52 +
1.53 + }
1.54 + ExecutionContext.Run(item.Context,
1.55 + delegate { item.Callback(item.State); }, null);
1.56 + }
1.57 + finally
1.58 + {
1.59 + lock (_callbacks)
1.60 + {
1.61 + if (item != null)
1.62 + _threads.Remove(item);
1.63 + }
1.64 + }
1.65 + }
1.66 +
1.67 + public bool IsMyThread(Thread thread)
1.68 + {
1.69 + lock (_callbacks)
1.70 + {
1.71 + foreach (Thread t in _threads.Values)
1.72 + {
1.73 + if (t == thread)
1.74 + return true;
1.75 + }
1.76 + return false;
1.77 + }
1.78 + }
1.79 +
1.80 + public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
1.81 + {
1.82 + if (item == null)
1.83 + throw new ArgumentNullException("item");
1.84 + lock (_callbacks)
1.85 + {
1.86 + LinkedListNode<WorkItem> node = _callbacks.Find(item);
1.87 + if (node != null)
1.88 + {
1.89 + _callbacks.Remove(node);
1.90 + return WorkItemStatus.Queued;
1.91 + }
1.92 + else if (_threads.ContainsKey(item))
1.93 + {
1.94 + if (allowAbort)
1.95 + {
1.96 + _threads[item].Abort();
1.97 + _threads.Remove(item);
1.98 + return WorkItemStatus.Aborted;
1.99 + }
1.100 + else
1.101 + return WorkItemStatus.Executing;
1.102 + }
1.103 + else
1.104 + return WorkItemStatus.Completed;
1.105 + }
1.106 + }
1.107 +
1.108 + public void CancelAll(bool allowAbort)
1.109 + {
1.110 + lock (_callbacks)
1.111 + {
1.112 + _callbacks.Clear();
1.113 + if (allowAbort)
1.114 + {
1.115 + foreach (Thread t in _threads.Values)
1.116 + t.Abort();
1.117 + }
1.118 + }
1.119 + }
1.120 + }
1.121 +}