-
-
Save zezba9000/07ded92c1850a29c2b77a39d5a6b475f to your computer and use it in GitHub Desktop.
C# Threaded Jobs
This file contains hidden or 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.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