2010-09-15 30 views
0

我在一个线程中有一些代码。该代码的主要功能是调用其他方法,它写的东西到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代码的第三方类。目前我无法访问其内部。

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

问题是,随着时间的推移(几个小时),AddNewTestParameter方法调用花费的时间越来越长,从大约10ms开始到大约1sec。

q是包含写入数据库所需信息的对象的队列。这些项目由主线程添加到此队列中。线程只是把它们拿出来写出来,然后把它们处理掉。 q.Count不超过1,尽管随着数据库写入速度变慢,q.Count上升,因为出队无法赶上。最糟糕的是,q.Count超过了3万。我总共向数据库写入了超过150,000个条目。

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

所以,目前,我有2个疑虑:

  1. 我的代码的问题。该线程是低优先级的,也许这可能会影响性能。另外,在观看20分钟的内存使用情况后,我看到它以约100K/min的速度上升,CPU利用率在%2-5左右似乎保持不变。我怎样才能找出内存泄漏发生的地方?我可以将它指向代码的特定部分吗?

  2. 第三方代码是问题。我怎么能证明这一点?有什么方法可以观察并确认问题在于第三方代码?

+0

使用内存分析器。 – 2010-09-15 15:18:12

回答

2

无论如何,如果我不得不做出一个建议,我想看看DBTables ...如果,也许是一个收集你忘了所以每次你怎么称呼它有一个更多的元素重新设置......所以经过一段时间的第三方例程,即O(n^2),或类似的东西,开始退化,因为它预计最糟糕的情况下20桌子,你提供1000.

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

EDIT2:好,另一种方法,让我们假设AddNewTestParameter不正是什么是说,它不...添加随后被添加到内部集合了新的参数。现在,有两种选择,如果是这种情况,要么在每次迭代后调用“ClearParameters”函数来清除该集合,然后这将是你的错,或者你没有这样的功能,然后它是第三代码故障。这也可以解释你的内存丢失(也可能与队列增长有关)

+0

对不起,我做了一些编辑,希望清除一些混淆。 – sbenderli 2010-09-15 14:06:39

+0

DbTables是一个对象。它有8个属性,每个属性都指向一个表对象,它是第三方对象。我检查过以确保我没有创建新的DbTables,它始终是相同的DbTables对象。 – sbenderli 2010-09-15 14:35:06

相关问题