Created
February 9, 2012 16:31
-
-
Save thoemmi/1780927 to your computer and use it in GitHub Desktop.
SingleThreadedTaskScheduler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace SingleThreadedTaskSchedulerDemo { | |
public class SingleThreadedTaskScheduler : TaskScheduler, IDisposable { | |
private readonly string _backgroundThreadName; | |
private readonly object _backgroundThreadLock = new object(); | |
private volatile Thread _backgroundThread; | |
private BlockingCollection<Task> _tasks = new BlockingCollection<Task>(); | |
public SingleThreadedTaskScheduler(string backgroundThreadName) { | |
_backgroundThreadName = backgroundThreadName; | |
} | |
protected override void QueueTask(Task task) { | |
EnsureBackgroundThread(); | |
_tasks.Add(task); | |
} | |
private void EnsureBackgroundThread() { | |
if (_backgroundThread == null) { | |
lock (_backgroundThreadLock) { | |
if (_backgroundThread == null) { | |
var thread = new Thread(OnStart) { | |
Name = _backgroundThreadName, | |
IsBackground = true | |
}; | |
thread.Start(); | |
_backgroundThread = thread; | |
} | |
} | |
} | |
} | |
private void OnStart() { | |
foreach (var t in _tasks.GetConsumingEnumerable()) { | |
TryExecuteTask(t); | |
} | |
} | |
public override int MaximumConcurrencyLevel { | |
get { return 1; } | |
} | |
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { | |
if (Thread.CurrentThread.ManagedThreadId != _backgroundThread.ManagedThreadId) { | |
return false; | |
} | |
if (taskWasPreviouslyQueued && !TryDequeue(task)) { | |
return false; | |
} | |
return TryExecuteTask(task); | |
} | |
protected override IEnumerable<Task> GetScheduledTasks() { | |
return _tasks.ToArray(); | |
} | |
public void Dispose() { | |
if (_tasks != null) { | |
// Indicate that no new tasks will be coming in | |
_tasks.CompleteAdding(); | |
// Wait for thread to finish processing tasks | |
_backgroundThread.Join(); | |
// Cleanup | |
_tasks.Dispose(); | |
_tasks = null; | |
_backgroundThread = null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple
TaskScheduler
implementation where all tasks are executed in a single background thread.I needed this to synchronize the communication with a hardware device.
The implementation is based on Samples for Parallel Programming.