Created
December 19, 2018 08:51
-
-
Save RyuaNerin/5947c471039ddc6084303475a155fd7f to your computer and use it in GitHub Desktop.
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 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