119 lines
2.3 KiB
C#
119 lines
2.3 KiB
C#
// Stephen Toub
|
|
// stoub@microsoft.com
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace Aga.Controls.Threading
|
|
{
|
|
public class AbortableThreadPool
|
|
{
|
|
private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
|
|
private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
|
|
|
|
public WorkItem QueueUserWorkItem(WaitCallback callback)
|
|
{
|
|
return QueueUserWorkItem(callback, null);
|
|
}
|
|
|
|
public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
|
|
{
|
|
if (callback == null) throw new ArgumentNullException("callback");
|
|
|
|
WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
|
|
lock (_callbacks)
|
|
{
|
|
_callbacks.AddLast(item);
|
|
}
|
|
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
|
|
return item;
|
|
}
|
|
|
|
private void HandleItem(object ignored)
|
|
{
|
|
WorkItem item = null;
|
|
try
|
|
{
|
|
lock (_callbacks)
|
|
{
|
|
if (_callbacks.Count > 0)
|
|
{
|
|
item = _callbacks.First.Value;
|
|
_callbacks.RemoveFirst();
|
|
}
|
|
if (item == null)
|
|
return;
|
|
_threads.Add(item, Thread.CurrentThread);
|
|
|
|
}
|
|
ExecutionContext.Run(item.Context,
|
|
delegate { item.Callback(item.State); }, null);
|
|
}
|
|
finally
|
|
{
|
|
lock (_callbacks)
|
|
{
|
|
if (item != null)
|
|
_threads.Remove(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsMyThread(Thread thread)
|
|
{
|
|
lock (_callbacks)
|
|
{
|
|
foreach (Thread t in _threads.Values)
|
|
{
|
|
if (t == thread)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
|
|
{
|
|
if (item == null)
|
|
throw new ArgumentNullException("item");
|
|
lock (_callbacks)
|
|
{
|
|
LinkedListNode<WorkItem> node = _callbacks.Find(item);
|
|
if (node != null)
|
|
{
|
|
_callbacks.Remove(node);
|
|
return WorkItemStatus.Queued;
|
|
}
|
|
else if (_threads.ContainsKey(item))
|
|
{
|
|
if (allowAbort)
|
|
{
|
|
_threads[item].Abort();
|
|
_threads.Remove(item);
|
|
return WorkItemStatus.Aborted;
|
|
}
|
|
else
|
|
return WorkItemStatus.Executing;
|
|
}
|
|
else
|
|
return WorkItemStatus.Completed;
|
|
}
|
|
}
|
|
|
|
public void CancelAll(bool allowAbort)
|
|
{
|
|
lock (_callbacks)
|
|
{
|
|
_callbacks.Clear();
|
|
if (allowAbort)
|
|
{
|
|
foreach (Thread t in _threads.Values)
|
|
t.Abort();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|