私はしばらくの間、単純なカスタムスレッドプールを見つけようとしていましたが、見つからないので、素早く貧しい人のスレッドプールを作成しました。C#。カスタムスレッドプール用の.NETクラス
質問:
すでにこれを行うことができます任意の.NETクラスはありますか? (これを見つけるために何度も試みた後、それを見つけることができず、これよりもはるかに複雑なブログ投稿のカスタム実装のみ!)。
スレッドプールでタスクをポーリングしたり、タスクを開始したりしてスレッドを消費する方が良いですか? < 1kタスク/日。
[Fact] public void Test() { var sb = new StringBuilder(); Console.SetOut(new StringWriter(sb)); var resetEvent = new ManualResetEventSlim(); AddItem("A", 100); AddItem("B", 250); AddItem("C", 100); AddItem("D", 100); AddItem("E", 100); AddItem("G", 100,() => { Thread.Sleep(250); resetEvent.Set(); }); resetEvent.Wait(2500); Assert.True(resetEvent.IsSet); _output.WriteLine(""); _output.WriteLine("------------------ Test Finished ------------------"); _output.WriteLine("------------------ Console Out ------------------"); _output.WriteLine(""); _output.WriteLine(sb.ToString()); }
、正しい(または十分に正しい)である。この出力を得る
:これはケストレル
コード
public class WorkerQueue : IWorkerQueue
{
private readonly Queue<WorkItem> _items = new Queue<WorkItem>();
private int _max = 2; // Would be configurable
private int _running;
private Stopwatch _stopwatch;
public WorkerQueue()
{
_stopwatch = new Stopwatch();
_stopwatch.Start();
}
public void Add(WorkItem workItem)
{
lock (_items)
{
if (_running >= _max)
{
Log($"Queuing Item {workItem.Name} - _running >= _max");
_items.Enqueue(workItem);
return;
}
_running++;
Log($"Running Item {workItem.Name} - _running = {_running}");
var task = Task.Run(workItem.Action);
task.ContinueWith(t => OnActionCompleted(workItem.Name));
}
}
private void Log(string msg)
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} @ {_stopwatch.ElapsedMilliseconds}ms : {msg}");
}
private void OnActionCompleted(string obj)
{
Log($"OnActionCompleted {obj}");
WorkItem item = null;
lock (_items)
{
if (_items.Count > 0)
item = _items.Dequeue();
else
_running--;
}
if (item != null)
{
// Potential Stack Overflow if big queue builds up?
// Probably should be a while loop rather than recursion?
Log($"Running Next Item {item.Name}");
item.Action();
OnActionCompleted(item.Name);
}
else
{
Log($"Sleeping. _running = {_running}");
}
}
}
とテストにAspNetCoreサイトとして実行されています
Thread 14 @ 8ms : Running Item A - _running = 1
Thread 14 @ 8ms : Running Item B - _running = 2
Thread 14 @ 8ms : Queuing Item C - _running >= _max
Thread 14 @ 8ms : Queuing Item D - _running >= _max
Thread 14 @ 8ms : Queuing Item E - _running >= _max
Thread 14 @ 8ms : Queuing Item G - _running >= _max
Thread 21 @ 110ms : OnActionCompleted A
Thread 21 @ 110ms : Running Next Item C
Thread 21 @ 211ms : OnActionCompleted C
Thread 21 @ 211ms : Running Next Item D
Thread 20 @ 260ms : OnActionCompleted B
Thread 20 @ 260ms : Running Next Item E
Thread 21 @ 311ms : OnActionCompleted D
Thread 21 @ 311ms : Running Next Item G
Thread 20 @ 360ms : OnActionCompleted E
Thread 20 @ 360ms : Sleeping. _running = 1
Thread 21 @ 662ms : OnActionCompleted G
Thread 21 @ 662ms : Sleeping. _running = 0
http://codereview.stackexchange.comサイト –
に属している必要があるため、この質問を議論の対象としないように投票しています。@SergeyBerezovskiyは、すでにNETフレームワークで利用可能なものがあるか –
タスクは.NETCoreの新しいスレッドで、スレッドプール経由で管理されます。 –