Skip to content

Instantly share code, notes, and snippets.

@thoemmi
Created February 9, 2012 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thoemmi/1780927 to your computer and use it in GitHub Desktop.
Save thoemmi/1780927 to your computer and use it in GitHub Desktop.
SingleThreadedTaskScheduler
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;
}
}
}
}
@thoemmi
Copy link
Author

thoemmi commented Feb 9, 2012

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment