Время выполнения потокового кода увеличивается медленно. Как определить виновника? - PullRequest
0 голосов
/ 15 сентября 2010

У меня есть код в потоке.Основная функция кода - вызывать другие методы, которые записывают данные в базу данных 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 занимает все больше и больше времени, начиная от 10 мс до 1 с.

q - это очередь с объектами, которые содержат необходимую информацию для записи в базу данных.Элементы добавляются в эту очередь основным потоком.Нить просто извлекает их, записывает и избавляется от них.Значение q.Count не превышает 1, хотя со временем, когда запись в базу данных замедляется, число q.Count увеличивается, поскольку удаление из очереди не может наверстать упущенное.В худшем случае количество q.Count превысило 30000.Всего я записываю в базу данных более 150 000 записей.

На стороне SQL я провел несколько трассировок на сервере, и трассировка показывает, что внутренне SQL всегда занимает около 10 мс, даже в то время, когда сам код C #занимает 1 сек.

Итак, в настоящее время у меня есть 2 подозрения:

  1. Мой код является проблемой.Поток имеет низкий приоритет, возможно, это может повлиять на производительность.Кроме того, после просмотра использования памяти в течение 20 минут, я вижу, что она увеличивается примерно на 100 К / мин, загрузка ЦП кажется постоянной около% 2-5.Как я могу выяснить, где происходит утечка памяти?Могу ли я указать его на определенную часть кода?

  2. Проблема заключается в коде третьей стороны.Как я могу доказать это?Какие методы можно посмотреть и подтвердить, что проблема заключается в стороннем коде?

1 Ответ

2 голосов
/ 15 сентября 2010

Во всяком случае, если бы мне пришлось сделать предложение, я бы посмотрел на DBTables ... если это коллекция, может быть, вы забыли сбросить ее, поэтому каждый раз, когда вы называете ее, у нее есть еще один элемент ... так что через некоторое времяСторонняя подпрограмма O (n ^ 2) или что-то в этом роде начинает ухудшаться, поскольку она ожидает сценарий наихудшего случая из 20 таблиц, а вы предоставляете 1000.

Редактировать: Хорошо, я бы отказался от проблемы, связанной с нахождением в очереди, поскольку снятие очереди должно быть очень быстрой операцией (вы можете измерить ее в любом случае).Он по-прежнему указывает на то, что коллекция DBTables становится все больше и больше, проверяли ли вы ее размер после первых x итераций?

Edit2: Хорошо, еще один подход, скажем, AddNewTestParameter делает точно что говорит, что делает ... ДОБАВИТЬ новый параметр, который затем добавляется во внутреннюю коллекцию.Теперь, есть два варианта, если это так, либо вы должны очистить эту коллекцию, вызывая функцию «ClearParameters» после каждой итерации, и тогда это будет вашей ошибкой, или у вас нет такой функциональности, и тогда это третий коднеисправность.Это также объясняет потерю памяти (хотя это также может быть связано с растущей очередью)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...