none
Como aumentar timeout em conexão com banco SQL [C#]??

    Pergunta

  • Tenho um projeto web asp.net e no code-behind de uma das páginas faço acesso ao banco de dados. Como a consulta é demorada, estou tendo o problema de timeout. Aparece a seguinte mensagem antes da consulta terminar: "Tempo limite expirou. O tempo limite esgotou antes da conclusão da operação ou o servidor não está respondendo."

    O código através do qual faço a conexão é:

    string sConnection = "";
        string sSQL = "";
        SqlConnection conn;
    
        sConnection = @"Data Source = xxxx\sqlserver; User ID =xx; Password = xxxxx; Initial Catalog = xxxxx";
        conn = new SqlConnection(sConnection);
        conn.Open();
    
        sSQL = "JISP_RelVendaXMetaTrafego '20080801','20080831', 0, 1";
    
        DataSet dsVendaMetaTrafego = new DataSet();
        SqlDataAdapter DataAdapter = new SqlDataAdapter(sSQL, conn);
        DataAdapter.Fill(dsVendaMetaTrafego, "VendaMetaTrafego"); ****
    
        DataSet dsAux = new DataSet("Aux");
        DataTable tbAux = new DataTable("tbAux");
        dsAux.Tables.Add(tbAux);
    Na hora do Fill (instrução onde se encontra o ****, no código acima), fica parado, efetuando a consulta mas, antes de terminar, dá o erro do timeout.


    Como que posso fazer para aumentar esse tempo de espera??

    Desde já agradeço.
    quarta-feira, 5 de agosto de 2009 12:59

Respostas

  • Leonardo,

    O SqlDataAdapter utiliza o SelectCommand quando executa o método Fill. Portanto faça o seguinte antes do Fill.

    DataAdapter.SelectCommand.CommandTimeOut = XX;

    onde XX seria o timeout em segundos.

    Segue link de ajuda:

    SqlCommand.CommandTimeout Property
    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx

    Att.

    Ari C. Raimundo

    • Marcado como Resposta Leonardo_Cruz quarta-feira, 5 de agosto de 2009 15:13
    quarta-feira, 5 de agosto de 2009 13:15
    Moderador
  • Olá Leonardo,

    O que o método Fill do SqlDataAdapter faz, é executar o comando SQL ou procedure que está definido no SelectCommand, e ler os resultados para um DataSet/DataTable, por isso, para definir o timeout do Fill, basta alterar o Timeout desse SelectCommand. Algo como:

    // ...
    // Altera o Timeout de execução da consulta para 1 minuto (o padrão é 30 segundos)
    DataAdapter.SelectCommand.CommandTimeout = TimeSpan.FromMinutes(60).Seconds;
    DataAdapter.Fill(dsVendaMetaTrafego,
    "VendaMetaTrafego");

    // ...


    No entanto, dependendo do tempo que a sua consulta demora, pode não ser suficiente por se tratar de uma página web... O fato é que a página web tem um timeout de 90 segundos por padrão, por isso, se a sua consulta demorar mais do que isso, não bastará apenas alterar o timeout do comando SQL... Terá que alterar também o timeout de execução da página através da propriedade ScriptTimeout da classe HttpServerUtility:

    // Define o Timeout de execução da página ASPX
    HttpServerUtility.ScriptTimeout = TimeSpan.FromMinutes(60).Seconds;

     

    ---

    De qualquer forma, aumentar o timeout da execução dos comandos e/ou das páginas normalmente não é a melhor solução... Até porque você não quer deixar seu usuário esperando vários minutos pelo resultado de uma consulta...

    O ideal mesmo é analisar o plano de execução da sua consulta e avaliar se está utilizando os índices corretamente, e ver o que é possível melhorar. Em última instância, pode ainda pensar em outras alternativas para obter essa consulta (replicação, processos batch, desnormalização, entre outros)...

    Abraços,
    Caio Proiete



    Caio Proiete
    Microsoft MVP, MCT, MCPD, MCTS, MCSD
    http://caioproiete.net
    quarta-feira, 5 de agosto de 2009 13:54
    Moderador

Todas as Respostas

  • Leonardo,

    O SqlDataAdapter utiliza o SelectCommand quando executa o método Fill. Portanto faça o seguinte antes do Fill.

    DataAdapter.SelectCommand.CommandTimeOut = XX;

    onde XX seria o timeout em segundos.

    Segue link de ajuda:

    SqlCommand.CommandTimeout Property
    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx

    Att.

    Ari C. Raimundo

    • Marcado como Resposta Leonardo_Cruz quarta-feira, 5 de agosto de 2009 15:13
    quarta-feira, 5 de agosto de 2009 13:15
    Moderador
  • Olá Leonardo,

    O que o método Fill do SqlDataAdapter faz, é executar o comando SQL ou procedure que está definido no SelectCommand, e ler os resultados para um DataSet/DataTable, por isso, para definir o timeout do Fill, basta alterar o Timeout desse SelectCommand. Algo como:

    // ...
    // Altera o Timeout de execução da consulta para 1 minuto (o padrão é 30 segundos)
    DataAdapter.SelectCommand.CommandTimeout = TimeSpan.FromMinutes(60).Seconds;
    DataAdapter.Fill(dsVendaMetaTrafego,
    "VendaMetaTrafego");

    // ...


    No entanto, dependendo do tempo que a sua consulta demora, pode não ser suficiente por se tratar de uma página web... O fato é que a página web tem um timeout de 90 segundos por padrão, por isso, se a sua consulta demorar mais do que isso, não bastará apenas alterar o timeout do comando SQL... Terá que alterar também o timeout de execução da página através da propriedade ScriptTimeout da classe HttpServerUtility:

    // Define o Timeout de execução da página ASPX
    HttpServerUtility.ScriptTimeout = TimeSpan.FromMinutes(60).Seconds;

     

    ---

    De qualquer forma, aumentar o timeout da execução dos comandos e/ou das páginas normalmente não é a melhor solução... Até porque você não quer deixar seu usuário esperando vários minutos pelo resultado de uma consulta...

    O ideal mesmo é analisar o plano de execução da sua consulta e avaliar se está utilizando os índices corretamente, e ver o que é possível melhorar. Em última instância, pode ainda pensar em outras alternativas para obter essa consulta (replicação, processos batch, desnormalização, entre outros)...

    Abraços,
    Caio Proiete



    Caio Proiete
    Microsoft MVP, MCT, MCPD, MCTS, MCSD
    http://caioproiete.net
    quarta-feira, 5 de agosto de 2009 13:54
    Moderador
  • Ari e Caio,

    agradeço muito a atenção.

    Primeiramente fiz da maneira que o Ari citou e o problema do timeout da consulta foi sanado mas, em alguns casos, ocorria o que o Caio citou: o tempo de espera da página estava baixo e dava erro. Adicionei as instruções citadas pelo Ari, depois a do Caio e deu tudo certo. Muito obrigado!

    Quanto a demora de resposta da consulta SQL, eu também acho que deveria dar uma melhorada nela mas acontece que eu já pego essas procedures prontas. É função de outras pessoas produzir e disponibilizá-las e eu não tenho permissão para alterar ..

    Abraços a todos.
    quarta-feira, 5 de agosto de 2009 15:22
  • Olá Desenvolvedores, Boa Tarde!

    Aproveitando o tópico sobre TimeOut...segue trecho de meu código.

    Onde posso especificar um tempo maior ?

    public

    string vCon = "Data Source=192.999.0.999;Initial Catalog=DB_Devolucao;Persist Security Info=True;User ID=devolucaodev;pwd=dev";

     

    string vsele = "SELECT...";

     

    SqlCommand vquery = new SqlCommand(vsele, sqlconn);

     

    SqlDataReader dr = vquery.ExecuteReader();

     

    Abraços


    Gilberto Herminio Programador Pleno III (C#+FiveWin/xHarbour) Mogi das Cruzes-SP gil_haf@ig.com.br gil_haf@hotmail.com
    quinta-feira, 1 de julho de 2010 18:00
  • Gilberto,

    Modifique a propriedade CommandTimeOut do seu comando. Por exemplo:

    // altera timeout para 2 minutos
    vquery.CommandTimeOut = 120;

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com  

    sexta-feira, 2 de julho de 2010 01:06
    Moderador