【发布时间】:2016-01-25 22:01:50
【问题描述】:
有一堆压缩数据块必须异步压缩 - 不能以任何形式或形式阻塞或减慢主线程。
解压后的块将被主线程使用。
目前我是这样做的:
foreach (var chunkPair in compressedChunkData)
{
var task = Task.Factory.StartNew<Chunk>(() =>
{
var compressedBytes = Convert.FromBase64String(chunkPair.Value);
var chunk = Decompress(compressedBytes);
return chunk;
}).ContinueWith((finishedTask) =>
{
var chunk = finishedTask.Result;
TaskFinishActions.Enqueue(() =>
{
chunk.PostSerialize();
document.Chunks.Add(chunkPair.Key, chunk);
});
});
}
// By the time we get here 20ms has passed!!!
问题在于,这似乎劫持了运行主线程的核心,从而扼杀了性能。
有没有办法让TaskFactory 仅在主线程被阻塞的那些短暂时刻让每个核心线程和上下文切换离开主线程?
编辑:foreach 循环并不是代码中唯一变慢的部分,只要有相当数量的解压任务在运行,主线程就会显着变慢。
EDIT2:解压的新数据一直到,循环不只跑一次:
- 假设您有 250 件物品首先到达
compressedChunkData - 下一帧你有 10 个项目,接下来是 12 个,接下来是 0 个,接下来是 2 个,等等。
【问题讨论】:
-
您可以针对您的问题将主线程优先级设置得尽可能高。您正在运行
forach,该循环的 20 毫秒不是正常且明显的吗? -
foreach 循环不像 260 项那样有问题。 4 核。
-
Rene Vogt,TaskcreationOptions.LongRunning 只会让情况变得更糟,因为这表明创建的线程比必要的多。
-
创建 260 个任务并不理想。如果你想要并行性,我会使用单个任务或
Task.Run(() => Parallel.ForEach(...))。 -
Charles Mager,是的,这似乎效果更好。
标签: c# concurrency task-parallel-library taskfactory