【问题标题】:Optimization program using ThreadPool. C#使用ThreadPool的优化程序。 C#
【发布时间】:2012-02-05 18:27:19
【问题描述】:

有了这个代码,很长一段时间以来,他都在不断地修补,他工作稳定而迅速。但似乎无法加快速度。很慢...

for (int jrCnt = rCnt; jrCnt <= arrayTable.GetUpperBound(0); jrCnt++)
{
    var prcI = new Price();

    /* here is the code search and add data to prcI */

    if ((!string.IsNullOrEmpty(prcI.name)) && (prcI.prc != 0))
    { // function add

        /* adding more information to prcI */

        ThreadPool.QueueUserWorkItem(delegate
        {
            if (!Accessor.AddProductUpdateProduct(prcI)) _updateCounter++;
            _countadd++;
        }); // I put the longest function in the streams
    }
}

这里我们调用函数。即使使用线程池,它也会运行很长时间。

public static bool AddProductUpdateProduct(Price price)
{
   using (var db = new PriceDataContext())
        {
            var matchedprod =
                db.Price.Where(x => x.name == price.name && x.company == price.company && x.date != price.date);

            if (matchedprod.Select(x=>x).Count() > 1)
            {
                db.Price.DeleteOnSubmit(matchedprod.First());
                db.SubmitChanges();
            }

            var matchedproduct = matchedprod.SingleOrDefault();

            if (matchedproduct != null)
            {
                matchedproduct.date = price.date;
                matchedproduct.prc = price.prc;

                db.SubmitChanges();
                return false;
            }
        }


/*here the code to add the product to the database.*/
return true;
}

请告诉我如何加快线程池的工作速度?

【问题讨论】:

  • 你真正想用你的代码做什么?首先,您查询某些项目的数据上下文。 如果返回的项目计数>1,则您再次查询数据上下文并获取第一个项目。然后在那之后,您在原始查询上运行SingleOrDefault() 并做一些事情?这根本没有意义......对于初学者来说,为什么要运行两次相同的查询?其次,如果您输入第一个 if 语句,您将永远输入第二个...如果matchedprod.Count() >2 会怎样?你只删除一项?这么多问题...

标签: c# optimization threadpool


【解决方案1】:

使用单独的线程不会加速任何应用程序。您所做的就是将处理从主线程转移到另一个线程。您需要将处理分成更小的部分,并将每个部分移动到单独的线程中以获得任何性能提升。

但是,在这种情况下它无济于事。有缺陷的是您的 LINQ 查询。 Enable debugging。查看生成的 SQL 并修复它们。

其次

if (matchedprod.SingleOrDefault() != null)
{
    matchedprod.SingleOrDefault().date = price.date;
    matchedprod.SingleOrDefault().prc = price.prc;

    db.SubmitChanges();
    return false;
}

这将查询数据库 3 次。每次调用 SingleOrDefault 一次。执行一次查询并将结果存储在变量中。

第三

matchedprodmatchedprodDel 有什么区别?他们的查询是相等的吗?

第四

这更容易阅读:

var matchedprod = db.Price.Where(x => x.name == price.name && x.company == price.company && x.date != price.date)

【讨论】:

  • 感谢您的帮助。照你说的做了。但不幸的是,这个比率并没有增加。
  • 我说了四件事。你做了哪一个?
  • 针对查询进行了优化。我已经更新了代码。如果有问题,请纠正我。至于你的第一块板,我不太了解它的实现。当然对不起。我是俄国人。而且我无法用英语快速思考......
【解决方案2】:

即使使用线程池,它也会运行很长时间。

错觉。如果一个方法需要 10 秒,那么进出一个线程需要 10 秒。线程不会神奇地提高函数的速度。

线程池的作用是它允许您并行运行 X 方法调用,但它们本身并没有变得更快。

现在,我将从调用开始 - 看,你有一些 SQL 执行时间不应该超过一毫秒,所以如果它很慢,我可以建议硬件过载或一些不太聪明的人不知道吗什么是索引,让 SQL 语句变得非常非常慢?

还要注意,除非预先配置,否则线程池会慢慢增加线程数——我认为每秒一个。所以如果你排队很多......你就死定了。

最后,你为什么要使用线程池而不是任务库?它并不是那么新......并且有更好的 API 和对线程的更多控制。

最后,使用分析器找出时间花在哪里。这并不难。没有分析器的编程就像试图在不加热任何东西的情况下做饭——你所做的事情是有限的。专业厨师?使用专业工具。

【讨论】:

  • 我正在使用 ThreadPool,因为我认为对于这个问题,它会是一个合适的解决方案。请告诉我正确的决定?非常感谢您帮助我解决了我的问题。
  • 任务库。或者至少告诉线程池使用高于正常数量的启动线程。再加上至少获得边缘专业人士并使用分析器。
【解决方案3】:

通常加速代码首先涉及使用所谓的“Profiler”。这是一个真正测量您的代码如何执行的工具(一直到源代码行级别)。

在进行任何优化之前,这应该始终是您的第一步。我自己的经验告诉我,纯粹猜测什么是慢的通常是错误的。相反,分析帮助我找到了需要优化的真正瓶颈。

所以我建议您首先使用分析器,我个人使用ANTS Performance Profiler(14 天免费试用)来检测您运行缓慢的代码行。

【讨论】:

  • 感谢您的回复。我会试试探查器。但是没有它,我可以说问题是更新数据库中的信息。当对数据库进行补充时,添加速度很快。导致我留下的问题的代码。我想指出,添加或更新了大约 9000 行。
猜你喜欢
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
相关资源
最近更新 更多