【问题标题】:Threaded code execution time rises slowly. How to determine the culprit?线程代码执行时间缓慢上升。如何确定罪魁祸首?
【发布时间】:2010-09-15 13:57:26
【问题描述】:

我在一个线程中有一些代码。该代码的主要功能是调用其他方法,这些方法将内容写入 SQL 数据库,如下所示:

private void doWriteToDb()
    {
        while (true)
        {
            try
            {
                if (q.Count == 0) qFlag.WaitOne();

                PFDbItem dbItem = null;
                lock (qLock)
                {
                    dbItem = q.Dequeue();
                }
                if (dbItem != null)
                {
                    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
                    //write it off
                    PFResult result = dbItem.Result;
                    double frequency = dbItem.Frequency;
                    int i = dbItem.InChannel;
                    int j = dbItem.OutChannel;
                    long detail, param, reading, res;
                    detail = PFCoreMethods.AddNewTestDetail(DbTables, _dicTestHeaders[result.Name.ToString().ToLower()]);

                    param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Frequency");
                    PFCoreMethods.AddNewTestParameterValue(DbTables, param, frequency.ToString());

                    param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "In channel");
                    PFCoreMethods.AddNewTestParameterValue(DbTables, param, i.ToString());

                    param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Out channel");
                    PFCoreMethods.AddNewTestParameterValue(DbTables, param, j.ToString());

                    param = PFCoreMethods.AddNewTestParameter(DbTables, detail, "Spec");
                    PFCoreMethods.AddNewTestParameterValue(DbTables, param, result.Spec);


                    dbItem.Dispose();
                    dqcnt++;
                    sw.Stop();
                }
            }
            catch (Exception ex)
            {


            }

        }
    }

AddNewTestParameter 方法使用具有 SQL 代码的第 3 方类。目前我无法访问它的内部。

DbTables 是一个集合对象,其属性是由 3rd 方程序创建的表对象。程序只使用一个 DbTable 对象。

问题是随着时间的推移(几个小时),AddNewTestParameter 方法调用的时间越来越长,从大约 10 毫秒到大约 1 秒。

q 是一个队列,其中的对象包含写入数据库所需的信息。这些项目由主线程添加到此队列中。线程只是将它们取出、写入并处理掉它们。 q.Count 不超过 1,尽管随着数据库写入速度变慢,q.Count 会上升,因为出队无法赶上。在最坏的情况下,q.Count 超过 30,000。我总共向数据库写入了超过 150,000 个条目。

在 SQL 端,我在服务器上运行了一些跟踪,跟踪显示内部 SQL 始终需要大约 10 毫秒,即使在 C# 代码本身需要 1 秒的时间。

所以,目前,我有两个怀疑:

  1. 我的代码是问题所在。该线程是低优先级的,也许这可能会影响性能。另外,观察内存使用 20 分钟后,我看到它以大约 100K/min 的速度上升,CPU 使用率似乎恒定在 %2-5 左右。如何确定内存泄漏发生在哪里?我可以将其定位到代码的特定部分吗?

  2. 第 3 方代码是问题所在。我怎么能证明这一点?有哪些方法可以观察和确认问题出在 3rd 方代码?

【问题讨论】:

    标签: c# performance memory


    【解决方案1】:

    无论如何,如果我不得不提出一个建议,我会看看 DBTables ...如果那是一个集合,也许你忘记重置它,所以每次你调用它时它都有一个元素......所以过了一会儿O(n^2) 或类似的第 3 方例程开始退化,因为它预计最坏的情况是 20 个表,而您提供 1000 个。

    编辑:好的,我会放弃队列中的问题,因为出队应该是一个非常快速的操作(无论如何你都可以测量它)。它仍然指向 DBTables 集合越来越大,你有没有在前 x 次迭代后检查它的大小?

    Edit2:好的,另一种方法,假设 AddNewTestParameter 完全按照它所说的...添加一个新参数,然后将其添加到内部集合.现在,有两种选择,如果是这种情况,您应该在每次迭代后通过调用“ClearParameters”函数来清除该集合,然后这将是您的错,或者您没有这样的功能,然后是第三个代码过错。这也可以解释你的记忆力下降(尽管这也可能与不断增长的队列有关)

    【讨论】:

    • 抱歉含糊不清,我做了一些修改,希望能消除一些混乱。
    • DbTables 是一个对象。它有 8 个属性,每个属性都指向一个表对象,该对象是第 3 方对象。我检查以确保我没有创建新的 DbTables,它始终是同一个 DbTables 对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 2012-05-23
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多