如何重用重新打开连接的代码?

Arn*_*und 1 c# ado.net refactoring c#-4.0

我们的生产服务器会终止非活动连接,因此我们的API需要在需要时恢复它们.以下代码有效,但它非常重复:

   private const int MaxRetryCount = 3;

    public static SqlDataReader RestoreConnectionAndExecuteReader(SqlCommand command)
    {
        int retryCount = 0;

        while (retryCount++ < MaxRetryCount)
        {
            try
            {
                if (command.Connection.State == ConnectionState.Closed)
                    command.Connection.Open();
                return command.ExecuteReader();
            }
            catch(Exception e)
            {
                if(!e.Message.ToLower().Contains("transport-level error has occurred"))
                {
                    throw;
                }
            }
        }
        throw new Exception("Failed to restore connection for command:"+command.CommandText);
    }

    public static void RestoreConnectionAndExecuteNonQuery(SqlCommand command)
    {
        var retryCount = 0;
        while(retryCount++ < MaxRetryCount)
        {
            try
            {
                if (command.Connection.State == ConnectionState.Closed)
                    command.Connection.Open();
                command.ExecuteNonQuery();
                return;
            }
            catch(Exception e)
            {
                if (!e.Message.ToLower().Contains("transport-level error has occurred"))
                {
                    throw;
                }
            }
        }
        throw new Exception("Failed to restore connection for command:" + command.CommandText);
    }
Run Code Online (Sandbox Code Playgroud)

我怎么能重构我的代码并消除重复?我需要保留这些方法的签名,因为它们在整个系统中使用.

Roy*_*ode 5

private const int MaxRetryCount = 3;

public static T RestoreConnectionAndExecute<T>(SqlCommand command, Func<SqlCommand, T> func)
{
    int retryCount = 0;

    while (retryCount++ < MaxRetryCount)
    {
        try
        {
            if (command.Connection.State == ConnectionState.Closed)
                command.Connection.Open();
            return func(command);
        }
        catch(Exception e)
        {
            if(!e.Message.ToLower().Contains("transport-level error has occurred"))
            {
                throw;
            }
        }
    }
    throw new Exception("Failed to restore connection for command:"+command.CommandText);

} 

public static SqlDataReader RestoreConnectionAndExecuteReader(SqlCommand command)
{
    return RestoreConnectionAndExecute(command, c => c.ExecuteReader());
}

public static int RestoreConnectionAndExecuteNonQuery(SqlCommand command)
{
    return RestoreConnectionAndExecute(command, c => c.ExecuteNonQuery());
}
Run Code Online (Sandbox Code Playgroud)