Объект SqlDataAdapter CommandTimeOut не работает в С#

Я использую SqlDataAdapter для извлечения результата из хранимой процедуры, которая занимает до 5 минут для выполнения и возврата результата.

я использую

da.SelectCommand.CommandTimeout = 1800;

настройка, но таймаут не работает. Код не учитывает тайм-аут в реальном времени. Не получается раньше.

Любая идея, как исправить этот тайм-аут?

Это мой код:

var cpdbconn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQL"].ConnectionString);   

using (SqlCommand cmd = new SqlCommand()) 
{
    cmd.Connection = cpdbconnection; 
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = readStoredProcedureName;

    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
    {
        try
        {
            da.SelectCommand.CommandTimeout = 1800;
            da.Fill(dt);

            // Check datatable is null or not
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow dataRow in dt.Rows)
                {
                    lstring.Add(Convert.ToString(dataRow["ServerName"]));
                }
            }

            // Add "','" in each row to convert the result to support nested query format
            InnerQryResultStr = string.Join("','", lstring.ToArray());

            if (multinestedQry != null)
            {
                combinedQry = qryName;
                qryName = multinestedQry + "('" + InnerQryResultStr + "')";
            }
            else
            {
                qryName = qryName + "('" + InnerQryResultStr + "')";
            }
        }
        catch (SqlException e)
        {
            Logger.Log(LOGTYPE.Error, String.Format("Inserting Data Failed for server {0} with Exception {1}", "DiscreteServerData", e.Message));

            if(e.Number == -2)
            {
                Logger.Log(LOGTYPE.Error, String.Format("TimeOut occurred while executing SQL query / stored procedure ", "DiscreteServerData", e.Message));
            }

            strMsg = e.Message.ToString();
            file.WriteLine(strMsg.ToString());
        }
    }
}

person Umapathy    schedule 07.11.2019    source источник
comment
Хранимая процедура занимает до 5 минут, чтобы выполнить результат. Что вы делаете со своей бедной БД, выполнение которой занимает 5 минут? Нормальное время отклика измеряется в миллисекундах. Возможно, потребуется небольшой редизайн, чтобы избежать этих 5 минут.   -  person Christopher    schedule 07.11.2019
comment
Так же есть куча таймаутов. CommandTimeout, Connection Timeout, Timeouts сервера на другом конце, обнаружение Slow Lorris и т. д.   -  person Christopher    schedule 07.11.2019
comment
StoredProdcuede производит миллионы записей. поэтому ожидаемое время выполнения SP   -  person Umapathy    schedule 07.11.2019


Ответы (2)


Вы пытались установить тайм-аут в SqlCommand? cmd.CommandTimeout = 300;

person demp    schedule 07.11.2019
comment
Добавление тайм-аута в строку подключения и приведенную выше строку помогло мне решить проблему. - person Umapathy; 07.03.2020

При работе с базой данных необходимо учитывать целый ряд тайм-аутов:

У команды время ожидания истекло.

Время ожидания подключения истекло.

Каждый уровень сетевой части имеет тайм-аут.

Сервер на другом конце имеет тайм-аут.

Сервер на другом конце может иметь защиту от медленных лори.

Время блокировки и транзакции может истечь (потому что в какой-то момент кто-то еще может захотеть работать с этой таблицей).

Согласно вашим комментариям, ваша хранимая процедура возвращает «миллионы записей». Вероятно, в этом и заключается проблема. Это непригодный для использования запрос. Это так много данных, что это выходит за рамки простой проблемы с сетью или БД и, возможно, становится проблемой с памятью на клиенте.

Распространенной ошибкой является извлечение слишком большого количества данных, даже если я не могу вспомнить ничего такого масштаба (самый большой был в 100 тысячах). У пользователя нет возможности обрабатывать такого рода информацию, поэтому должно быть больше фильтрации, нумерации страниц и тому подобного. Никогда не выполняйте эти шаги в клиенте. В лучшем случае вы передаете бесполезные объемы данных по сети. В худшем случае вы столкнетесь с тайм-аутами и проблемами параллелизма. Всегда выполняйте как можно больше фильтрации, разбиения на страницы и т. д. в запросе.

Вы хотите получить как можно меньше данных в целом. Массовые операции, такие как слияние, резервное копирование и т. д., обычно должны выполняться в СУБД. Если вы переместите его на клиент, вы только добавите еще один уровень отказа и два сетевых пути для данных.

Для лучшего ответа мне понадобится более точная информация о проблеме.

person Christopher    schedule 07.11.2019