【问题标题】:BackgroundWorker or Task.WhenAllBackgroundWorker 或 Task.WhenAll
【发布时间】:2018-03-27 11:44:14
【问题描述】:

我现在正在使用后台服务来处理耗时的操作,同时在 UI 中显示进度

但现在在时间方面寻找一些性能改进[因为目前后台工作人员需要更多时间来完成处理]

目前Do_Work在后台worker中的解决方案是这样的

foreach(string _entry in ArrayList){

  //process the _entry(communicate to a service and store response in Db) and took almost 2-3 seconds for the completion
}

ArrayList 包含近 25000 条记录。所以现在几乎需要 25000*3 = 75000 秒的时间来进行处理

我正在考虑的新解决方案就像同时启动 50 个线程,每个线程 500 个项目,并等待所有线程完成类似这样的操作

int failed = 0;
var tasks = new List<Task>();            
for (int i = 1; i < 50; i++)
{
    tasks.Add(Task.Run(() =>
    {

        try
        {
            //Process 500 items from Array .(communicate to a service and store response in Db)
        }
        catch
        {
            Interlocked.Increment(ref failed);
            throw;
        }
    }));
}
Task t = Task.WhenAll(tasks);    //Runs 50 Threads         
try
{
    await t;
}
catch (AggregateException exc)
{
string _error="";
    foreach (Exception ed in t.Exception.InnerExceptions)
    {
       _error+=ed.Message;
    }
     MessageBox.Show(_error);
}
if (t.Status == TaskStatus.RanToCompletion)
    MessageBox.Show("All ping attempts succeeded.");
else if (t.Status == TaskStatus.Faulted)
    MessageBox.Show("{0} ping attempts failed", failed.ToString());

这是否有助于减少处理时间?或者一些更好的方法? 我尝试了 10 的小样本并进行了调试,但我看不出有太大的不同(我选择 WhenAll 有什么问题?)

【问题讨论】:

  • 嗯,你可以使用PLINQParallel.ForEach...
  • Process 500 items from Array 是做什么的?
  • 这一切都取决于核心机器的数量,所以如果你有两个核心机器并且如果你创建了 50 个线程,那么在这之间会有时间切片,这也会导致性能问题,你需要编码根据物理核心数
  • 这是 IO 限制还是 CPU 限制?
  • 更好的问题是,你的机器是否支持同时运行 50 个线程?

标签: c# multithreading backgroundworker


【解决方案1】:

您一次需要处理几条记录。

处理具有 n 个不同任务的 n 条记录。假设 n = 5。所以 5 个不同的任务 t1、t2、t3、t4 和 t5。一旦任何人完成了一行数据的处理,他们应该开始处理 t (1+n)、t (2+n)、t(3+n)、t(4+n)、t(5+n) 行等直到处理完所有记录。

将所有这些处理后的值存储到字典或列表中,以识别哪个属于哪个记录。

这就像递归函数。

我过去使用过这种方法,它确实提高了很多性能。您可以根据您的 PC 配置微调 n 的值

【讨论】:

  • 所以你建议使用 5 线程?而不是 BackgroundWorker
  • 不是线程,使用 Task 和 BackgroundWorker。从 Backgroundworker 调用一个函数并使用该函数的 5 个任务内幕。 5号不是固定的,保持为变量,你可以根据性能进行调整。
  • @JibinMathew 如果您能够使用我建议的方法提高性能,请将其标记为答案。
  • 如果您需要更多帮助,请告诉我
【解决方案2】:

我建议尝试BlockingCollection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2022-11-15
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    相关资源
    最近更新 更多