gpt4 book ai didi

c# - 任务后台 worker c#

转载 作者:太空狗 更新时间:2023-10-29 21:55:03 26 4
gpt4 key购买 nike

在 5 秒运行进程中,多个后台工作人员的表现是否优于任务?我记得在一本书中读到,Task 是为短时间运行的进程设计的。

我问的原因是这样的:

我有一个进程需要 5 秒才能完成,还有 4000 个进程要完成。起初我做了:

for (int i=0; i<4000; i++) {
Task.Factory.StartNewTask(action);
}

而且性能很差(第一分钟后,完成了 3-4 个任务,控制台应用程序有 35 个线程)。也许这很愚蠢,但我认为线程池会处理这种情况(它将所有操作放入队列中,当线程空闲时,它会采取操作并执行它)。

现在的第二步是手动做 Environment.ProcessorCount background workers,并将所有的 Action 放在一个 ConcurentQueue 中。所以代码看起来像这样:

var workers = new List<BackgroundWorker>();
//initialize workers

workers.ForEach((bk) =>
{
bk.DoWork += (s, e) =>
{
while (toDoActions.Count > 0)
{
Action a;
if (toDoActions.TryDequeue(out a))
{
a();
}
}
}

bk.RunWorkerAsync();
});

这表现得更好。即使我有 30 个后台工作人员(与第一个案例一样多的任务),它的表现也比任务好得多。

乐:

我这样开始任务:

    public static Task IndexFile(string file)
{
Action<object> indexAction = new Action<object>((f) =>
{
Index((string)f);
});

return Task.Factory.StartNew(indexAction, file);
}

Index 方法是这个:

    private static void Index(string file)
{
AudioDetectionServiceReference.AudioDetectionServiceClient client = new AudioDetectionServiceReference.AudioDetectionServiceClient();

client.IndexCompleted += (s, e) =>
{
if (e.Error != null)
{
if (FileError != null)
{
FileError(client,
new FileIndexErrorEventArgs((string)e.UserState, e.Error));
}
}
else
{
if (FileIndexed != null)
{
FileIndexed(client, new FileIndexedEventArgs((string)e.UserState));
}
}
};

using (IAudio proxy = new BassProxy())
{
List<int> max = new List<int>();
if (proxy.ReadFFTData(file, out max))
{
while (max.Count > 0 && max.First() == 0)
{
max.RemoveAt(0);
}
while (max.Count > 0 && max.Last() == 0)
{
max.RemoveAt(max.Count - 1);
}

client.IndexAsync(max.ToArray(), file, file);
}
else
{
throw new CouldNotIndexException(file, "The audio proxy did not return any data for this file.");
}
}
}

此方法使用 Bass.net 库从 mp3 文件中读取一些数据。然后使用异步方法将该数据发送到 WCF 服务。创建任务的 IndexFile(string file) 方法在 for 循环中被调用了 4000 次。这两个事件,FileIndexed 和 FileError 没有被处理,所以它们永远不会被抛出。

最佳答案

Tasks 性能这么差的原因是因为你挂载了太多的小任务(4000)。请记住,CPU 也需要调度任务,因此装载大量短期任务会给 CPU 带来额外的工作负载。更多信息可以在TPL的第二段中找到:

Starting with the .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code. However, not all code is suitable for parallelization; for example, if a loop performs only a small amount of work on each iteration, or it doesn't run for many iterations, then the overhead of parallelization can cause the code to run more slowly.

当您使用后台工作程序时,您将可能的事件线程数限制为 ProcessCount。这减少了很多调度开销。

关于c# - 任务后台 worker c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10744122/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com