Skip to content

Instantly share code, notes, and snippets.

@RyuaNerin
Created December 19, 2018 08:51
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 RyuaNerin/5947c471039ddc6084303475a155fd7f to your computer and use it in GitHub Desktop.
Save RyuaNerin/5947c471039ddc6084303475a155fd7f to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace test222
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start");
RunTask();
Console.WriteLine("done");
Console.WriteLine("start");
RunTask();
Console.WriteLine("done");
Console.WriteLine("press any key to exit");
Console.ReadKey();
}
static void RunTask()
{
var tasks = new Task<int>[10];
for (int i = 0; i < 10; ++i)
{
var ii = i;
tasks[i] = Task.Factory.StartNew(
e =>
{
Console.WriteLine($"wait : {ii}");
Thread.Sleep(ii * 1000);
Console.WriteLine($"done : {ii}");
return ii;
},
null,
CancellationToken.None,
TaskCreationOptions.None,
PriorityScheduler.BelowNormal);
}
Task.WaitAll(tasks);
for (int i = 0; i < 10; ++i)
{
var r = tasks[i].Result;
Console.WriteLine($"thread {i} Result : {r} ({(i == r ? "match" : "dismatch")})");
}
}
public class PriorityScheduler : TaskScheduler
{
public const string DefaultThreadName = "PriorityScheduler";
public static readonly PriorityScheduler Highest = new PriorityScheduler(ThreadPriority.Highest, 0, "PriorityScheduler (Highest)" );
public static readonly PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal, 0, "PriorityScheduler (AboveNormal)");
public static readonly PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal, 0, "PriorityScheduler (BelowNormal)");
public static readonly PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest, 0, "PriorityScheduler (Lowest)" );
private readonly string m_threadName;
private readonly int m_maximumConcurrencyLevel;
private readonly BlockingCollection<Task> m_tasks = new BlockingCollection<Task>();
private readonly Lazy<Thread>[] m_threads;
public PriorityScheduler(ThreadPriority priority, int concurrencyLevel, string threadName)
{
this.m_maximumConcurrencyLevel = concurrencyLevel > 0 ? concurrencyLevel : Math.Max(1, Environment.ProcessorCount);
this.m_threadName = threadName;
this.m_threads = new Lazy<Thread>[this.m_maximumConcurrencyLevel];
for (int i = 0; i < this.m_maximumConcurrencyLevel; ++i)
{
var ii = i;
this.m_threads[i] = new Lazy<Thread>(
() => new Thread(this.TaskWorker)
{
IsBackground = true,
Name = $"{this.m_threadName} - {ii}",
Priority = priority
}
);
}
}
public PriorityScheduler(ThreadPriority priority)
: this(priority, 0, DefaultThreadName)
{
}
private void TaskWorker()
{
foreach (var task in this.m_tasks.GetConsumingEnumerable())
base.TryExecuteTask(task);
}
public override int MaximumConcurrencyLevel
=> this.m_maximumConcurrencyLevel;
protected override IEnumerable<Task> GetScheduledTasks()
{
return this.m_tasks;
}
protected override void QueueTask(Task task)
{
this.m_tasks.Add(task);
if (!this.m_threads[0].IsValueCreated)
for (int i = 0; i < this.m_maximumConcurrencyLevel; i++)
this.m_threads[i].Value.Start();
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
protected override bool TryDequeue(Task task)
{
throw new NotImplementedException();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment