C#如果超时失败,请重试Sql查询

C#如果超时失败,请重试Sql查询,c#,sql-server,C#,Sql Server,此时,我的查询超时并导致失败。重试执行查询的最佳方式是什么 我在执行查询之前验证连接是否打开。但是,由于任何给定时间的服务器负载,可能需要一种通用方法来重试该操作 public static class Retry { public static void Do( Action action, TimeSpan retryInterval, int retryCount = 3) {

此时,我的查询超时并导致失败。重试执行查询的最佳方式是什么


我在执行查询之前验证连接是否打开。但是,由于任何给定时间的服务器负载,可能需要一种通用方法来重试该操作

 public static class Retry
    {
       public static void Do(
           Action action,
           TimeSpan retryInterval,
           int retryCount = 3)
       {
           Do<object>(() => 
           {
               action();
               return null;
           }, retryInterval, retryCount);
       }

       public static T Do<T>(
           Func<T> action, 
           TimeSpan retryInterval,
           int retryCount = 3)
       {
           var exceptions = new List<Exception>();

           for (int retry = 0; retry < retryCount; retry++)
           {
              try
              { 
                  if (retry > 0)
                      Thread.Sleep(retryInterval);
                  return action();
              }
              catch (Exception ex)
              { 
                  exceptions.Add(ex);
              }
           }

           throw new AggregateException(exceptions);
           }
        }

我用asp.net web表单编写了一个示例代码,运行了10次

        static int noOfTries = 0;
        protected void Page_Load(object sender, EventArgs e)
        {
            function();
        }

        private void function()
        {

            try
            {

                if (noOfTries == 10) goto XX;
                noOfTries++;
                int a = 0;
                int b = 1 / a;


            }
            catch (Exception ew)
            {
                Response.Write(ew.Message + "<br/>");
                function();

            }
            XX:
            int c = 0;
        }
static int noOfTries=0;
受保护的无效页面加载(对象发送方、事件参数e)
{
函数();
}
私有空函数()
{
尝试
{
如果(noOfTries==10)转到XX;
中午++;
int a=0;
int b=1/a;
}
捕获(异常ew)
{
响应。写入(ew.Message+“
”); 函数(); } XX: int c=0; }
注: 使用静态变量时,它不是线程安全的

static int noOfTries=0
多线程执行可能无法正常工作,除非静态变量将在多线程中共享

解决使用
Session[“noOfTries”]


如果是多线程执行环境。

请以某种方式重新构造代码,以便允许递归调用查询,直到获得所需的结果

例如

您可能希望能够控制程序尝试执行此操作的重试次数,以使其具有一定的灵活性

此外,如果您的查询需要很长时间,您应该研究如何优化SQL Server数据库,以借助视图/索引等减少执行时间。

使用Palmer library:

Retry.On().For(TimeSpan.FromSeconds(15)).With(context=>
{
//由于某些问题可能会定期失败的代码。
ExecuteQuery(字符串连接字符串、字符串查询)
if(contect.DidExceptionLastTime)
睡(200);//你想干什么都行
});
请参阅github页面上的API。例如,您可以检查上下文中是否存在异常,并决定在异常确实发生时休眠一段时间。 您可以重试更具体的异常。
您可以永远尝试,等等。

应实施指数退避。否则DB将在加载状态下死亡。我建议使用
wait Task.Delay(retryInterval)
而不是
Thread.Sleep
,因为Thread.Sleep会阻止当前线程。
Retry.Do(() => SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1));
        static int noOfTries = 0;
        protected void Page_Load(object sender, EventArgs e)
        {
            function();
        }

        private void function()
        {

            try
            {

                if (noOfTries == 10) goto XX;
                noOfTries++;
                int a = 0;
                int b = 1 / a;


            }
            catch (Exception ew)
            {
                Response.Write(ew.Message + "<br/>");
                function();

            }
            XX:
            int c = 0;
        }
private static void ExecuteQuery(string connectionString, string query)
{
    SqlConnection connection = new SqlConnection(connectionString);
    DataTable output = null;

    while output is null
    {
        output = getDataFromDB(query);
    }

    if(output is DataTable && output.Rows.Count > 0)
    {
        Console.WriteLine("There are " + output.Rows.Count + " clusters within the capacity analysis.");
    }
}

private DataTable getDataFromDB(string query)
{
    DataTable oDTResult = null;

    try
    {
        //create new SqlAdataAdapter
        SqlDataAdapter command = new SqlDataAdapter {SelectCommand = new SqlCommand(query, connection)};

        //connect to Sqldb
        connection.Open();

        //validate connection to database before executing query
        if (connection.State != ConnectionState.Open) return;
        Console.WriteLine("Connection successful\nExecuting query...");

        //set connection timeout
        command.SelectCommand.CommandTimeout = 200;

        //create new dataSet in order to input output of query to
        DataSet dataSet = new DataSet();

        //fill the dataSet
        command.Fill(dataSet, "capacity");
        DataTable dtTable1 = dataSet.Tables["capacity"];            

        oDTResult = dtTable1;
    }
    catch (Exception e)
    {
        Console.WriteLine("Unable to execute capacity (all records) query due to {0}", e.Message);
    }
    finally
    {
        connection.Close();

        Declarations.NumOfClusters = output.Rows.Count;
        Declarations.finalIssues = Issues(output, 2m, 20, true);

        Console.WriteLine("\n---------------Successfully Created Capacity DataSet---------------\n");
    }

    return oDTResult;
}
  Retry.On<Exception>().For(TimeSpan.FromSeconds(15)).With(context =>
  {
    // Code that might periodically fail due to some issues.
       ExecuteQuery(string connectionString, string query)
       if (contect.DidExceptionLastTime)
           Thread.Sleep(200); // what ever you wish
   });