first commit
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user