Skip to content

Instantly share code, notes, and snippets.

@zezba9000
Created March 26, 2017 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zezba9000/07ded92c1850a29c2b77a39d5a6b475f to your computer and use it in GitHub Desktop.
Save zezba9000/07ded92c1850a29c2b77a39d5a6b475f to your computer and use it in GitHub Desktop.
C# Threaded Jobs
using System;
using System.Threading;
namespace ThreadJobs
{
abstract class Job : IDisposable
{
private Thread thread;
private volatile bool waiting;
public bool Waiting {get{return waiting;}}
private volatile bool isDisposed;
public bool IsDisposed {get{return isDisposed;}}
public Job()
{
thread = new Thread(WorkerThread);
thread.Start();
}
private void WorkerThread()
{
waiting = true;
while (!isDisposed)
{
while (waiting) Thread.Sleep(1);
if (isDisposed) return;
Exec();
waiting = true;
}
}
protected abstract void Exec();
public void StartExec()
{
waiting = false;
}
public void Dispose()
{
isDisposed = true;
waiting = false;
}
}
abstract class JobManager<T> : IDisposable where T : Job, new()
{
protected T[] jobs;
public JobManager()
{
jobs = new T[Environment.ProcessorCount];
for (int i = 0; i != jobs.Length; ++i)
{
jobs[i] = new T();
}
}
public void WaitForJobsToFinish()
{
lock (jobs)
{
foreach (var job in jobs)
{
while (!job.Waiting) Thread.Sleep(1);
}
}
}
protected T QueJob()
{
while (true)
{
foreach (var job in jobs)
{
if (!job.Waiting) continue;
return job;
}
}
}
public void Dispose()
{
if (jobs != null)
{
foreach (var job in jobs) job.Dispose();
jobs = null;
}
}
}
class StreamPutDataJob : Job
{
public volatile int x = -1;
protected override void Exec()
{
//Bass.BASS_StreamPutData(outputs[x], buffer, length);// this could be called in parallel with others
Console.Write(x);
}
}
class StreamPutDataJobManager : JobManager<StreamPutDataJob>
{
public void QueJob(int x)
{
lock (jobs)
{
var job = QueJob();
job.x = x;
job.StartExec();
}
}
}
class Program
{
static void Main(string[] args)
{
using (var manager = new StreamPutDataJobManager())
{
// run jobs
for (int i = 0; i != 100; ++i)
{
manager.QueJob(i);
}
manager.WaitForJobsToFinish();
Console.WriteLine();
Console.WriteLine("All jobs ran on seprate threads! (Hit return)");
Console.ReadLine();
Console.WriteLine("Disposing...");
}
Console.WriteLine("Disposed! (Hit return to quit)");
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment