4 つの異なるセグメント (各セグメントは異なる長時間実行タスク) で単一のファイルをダウンロードし、定期的な間隔で進行状況をシリアル化するアプリケーションがあります。
シリアル化が 2 コア マシンで行われると、プロセスは 3 ~ 10 秒間ブロックされてから完了します。このブロッキング動作が初めて発生すると、二度と発生しません。シリアライズへの 2 回目から (n) 回目の呼び出しは、問題なくすぐに実行されます。フレームワークは、最初の呼び出しのブロック中に、ブロック動作が再び発生するのを防ぐタスク/スレッドの最適化を行ったようです。
誰かがこの最適化について何か洞察を持っていますか?初期化時にこのタイプの最適化を実行して、ブロッキング動作をすべて一緒に回避できるかどうか?
状況を説明するのに役立つ疑似コードを次に示します。
class Download
{
private DownloadSegment[] _downloadSegments = new DownloadSegment[4];
public void StartDownload()
{
for (int i = 0; i < 4; i++)
{
_downloadSegments[i] = new DownloadSegment();
_downloadSegments[i].Start();
}
}
public void Serialize()
{
try
{
//enter lock so the code does not serilize the progress while
//writing new downloaded info at the same time
foreach(DownloadSegment segment in _downloadSegments)
{
Monitor.Enter(segment.SyncRoot);
}
//code to serialize the progress
}
finally
{
foreach (DownloadSegment segment in _downloadSegments)
{
Monitor.Exit(segment.SyncRoot);
}
}
}
}
class DownloadSegment
{
public object SyncRoot = new object();
public void Start()
{
Task downloadTask = new Task(
() =>
{
//download code
lock (SyncRoot)
{
//wirte to disk code
}
},
new CancellationToken(),
TaskCreationOptions.LongRunning);
downloadTask.Start(TaskScheduler.Default);
}
}