Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3892 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
3 changed files with 124 additions and 16 deletions
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Threading; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Util |
||||
{ |
||||
/// <summary>
|
||||
/// A worker thread that normally sleeps, but can run a queue of commands.
|
||||
/// </summary>
|
||||
public class WorkerThread |
||||
{ |
||||
sealed class AsyncTask : IAsyncResult |
||||
{ |
||||
internal readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false); |
||||
internal readonly Action method; |
||||
volatile bool isCompleted; |
||||
|
||||
internal AsyncTask(Action method) |
||||
{ |
||||
this.method = method; |
||||
} |
||||
|
||||
internal void SetCompleted() |
||||
{ |
||||
isCompleted = true; |
||||
manualResetEvent.Set(); |
||||
} |
||||
|
||||
public bool IsCompleted { |
||||
get { return isCompleted; } |
||||
} |
||||
|
||||
public WaitHandle AsyncWaitHandle { |
||||
get { return manualResetEvent; } |
||||
} |
||||
|
||||
public object AsyncState { get; set; } |
||||
public bool CompletedSynchronously { get { return false; } } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs <paramref name="method"/> on the worker thread.
|
||||
/// </summary>
|
||||
/// <param name="method">The method to run.</param>
|
||||
/// <returns></returns>
|
||||
public IAsyncResult Enqueue(Action method) |
||||
{ |
||||
if (method == null) |
||||
throw new ArgumentNullException("method"); |
||||
AsyncTask task = new AsyncTask(method); |
||||
lock (lockObject) { |
||||
taskQueue.Enqueue(task); |
||||
Monitor.Pulse(lockObject); |
||||
} |
||||
return task; |
||||
} |
||||
|
||||
readonly object lockObject = new object(); |
||||
Queue<AsyncTask> taskQueue = new Queue<AsyncTask>(); |
||||
bool workerRunning = false; |
||||
|
||||
/// <summary>
|
||||
/// Runs the worker thread loop on the current thread.
|
||||
/// </summary>
|
||||
public void RunLoop() |
||||
{ |
||||
lock (lockObject) { |
||||
if (workerRunning) |
||||
throw new InvalidOperationException("There already is a worker running"); |
||||
workerRunning = true; |
||||
} |
||||
try { |
||||
while (workerRunning) { |
||||
AsyncTask task; |
||||
lock (lockObject) { |
||||
while (taskQueue.Count == 0) |
||||
Monitor.Wait(lockObject); |
||||
task = taskQueue.Dequeue(); |
||||
} |
||||
task.method(); |
||||
task.SetCompleted(); |
||||
} |
||||
} finally { |
||||
lock (lockObject) { |
||||
workerRunning = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Exits running the worker thread.
|
||||
/// </summary>
|
||||
public void ExitWorkerThread() |
||||
{ |
||||
Enqueue(delegate { workerRunning = false; }); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue