最近、このSemaphoreSlim
クラスを使用して、(大規模な)ストリーミングリソースで並列化可能な操作の進行中の作業を制限していることに気付きました。
// The below code is an example of the structure of the code, there are some
// omissions around handling of tasks that do not run to completion that should be in production code
SemaphoreSlim semaphore = new SemaphoreSlim(Environment.ProcessorCount * someMagicNumber);
foreach (var result in StreamResults())
{
semaphore.Wait();
var task = DoWorkAsync(result).ContinueWith(t => semaphore.Release());
...
}
これは、メモリに多くの結果をもたらし、プログラムが対処できないことを回避するためです(通常はOutOfMemoryExceptionによって証明されます)。コードは機能し、適度にパフォーマンスが優れていますが、それでも不自然に感じます。特に、someMagicNumber
乗数は、プロファイリングを介して調整されますが、最適ではない可能性があり、の実装の変更に対して回復力がありませんDoWorkAsync
。
スレッドプールが実行のために多くのものをスケジュールするという障害を克服できるのと同じように、利用可能なリソースに基づいてメモリにロードされる多くのものをスケジュールするという障害を克服できるものが欲しいです。
OutOfMemoryExceptionが発生するかどうかを決定論的に決定することは不可能であるため、私が探しているものは統計的手段によってのみ達成できるか、まったく達成できない可能性があることを理解していますが、何かが欠けていることを願っています。