一段时间后关闭互联网连接后如何重试连接数据库

时间:2018-07-16 09:16:59

标签: c# sql-server

我有一个内置于c#中的通知应用程序,用于通知数据库中的任何更改。该应用程序在后台运行。但是问题出在应用程序启动后,如果关闭了Internet,则应用程序将引发SQLException。我已经使用try catch来处理异常。但是我希望我的应用程序尝试连接数据库,并在建立连接后返回到主代码。

    try
            {
                using (SqlConnection connection =
       new SqlConnection(GetConnectionString()))
                {              
//i want to return here when the connection is reestablished

using (SqlCommand command =
                    new SqlCommand(GetListenerSQL(), connection))
                    {
                        connection.Open();

                        // Make sure we don't time out before the
                        // notification request times out.
                        command.CommandTimeout = NotificationTimeout;
                        SqlDataReader reader = command.ExecuteReader();
                        while (reader.Read())
                        {
                            messageText = System.Text.ASCIIEncoding.ASCII.GetString((byte[])reader.GetValue(13)).ToString();
                            // Empty queue of messages.
                            // Application logic could parse
                            // the queue data and 
                            // change its notification logic.
                        }

                        object[] args = { this, EventArgs.Empty };
                        EventHandler notify =
                        new EventHandler(OnNotificationComplete);
                        // Notify the UI thread that a notification
                        // has occurred.
                        this.BeginInvoke(notify, args);
                    }
                }
            }
            catch(SqlException e)
            {

            }

是否可以在没有goto语句的情况下进行操作。我希望避免使用goto语句。

3 个答案:

答案 0 :(得分:1)

从@Archer的建议中,我得到了解决方案。在catch块中,我再次调用该方法,该方法将在适当的时间后使用此连接。像

public void StartListener()
{
try
            {
                using (SqlConnection connection =
       new SqlConnection(GetConnectionString()))
                {              
//i want to return here when the connection is reestablished

using (SqlCommand command =
                    new SqlCommand(GetListenerSQL(), connection))
                    {
                        connection.Open();

                        // Make sure we don't time out before the
                        // notification request times out.
                        command.CommandTimeout = NotificationTimeout;
                        SqlDataReader reader = command.ExecuteReader();
                        while (reader.Read())
                        {
                            messageText = System.Text.ASCIIEncoding.ASCII.GetString((byte[])reader.GetValue(13)).ToString();
                            // Empty queue of messages.
                            // Application logic could parse
                            // the queue data and 
                            // change its notification logic.
                        }

                        object[] args = { this, EventArgs.Empty };
                        EventHandler notify =
                        new EventHandler(OnNotificationComplete);
                        // Notify the UI thread that a notification
                        // has occurred.
                        this.BeginInvoke(notify, args);
                    }
                }
            }
            catch(SqlException e)
            {
                 Thread.Sleep(2000);
                 StartListener();
            }
}

答案 1 :(得分:0)

如果失败,则应调用计时器,计时器应调用后台工作人员。 编写功能以检查后台工作人员中的连接。如果确实如此,则应停止计时器。并调用通常的程序

答案 2 :(得分:0)

我将重试逻辑移出查询方法。我在某个地方看到了一个不错的重试库,但是现在找不到。

public void StartListener()
{                    
    var message = GetMessage(); 
    //process message in some way
    object[] args = { this, EventArgs.Empty };
    EventHandler notify = OnNotificationComplete;                
    this.BeginInvoke(notify, args);                     
}

private const int TimeoutStep = 2000;
private const int MaxTimeout = 10000;

private string GetMessage(int timeout = 0)
{
    //prevent loop of endless retries
    if (timeout >= MaxTimeout)
    {
        //optional: define your own Exception class
        throw new MaxTimeoutException();
    }

    try
    {
        Thread.Sleep(timeout);
        return GetMessageFromDatabase();
    }
    catch (SqlException ex)
    {
        //log ex in debug mode at least               
        return GetMessage(timeout + TimeoutStep);
    }             
}

private string GetMessageFromDatabase()
{
    string message = null;
    using (var connection = new SqlConnection(GetConnectionString()))
    {
        using (var command = new SqlCommand(GetListenerSQL(), connection))
        {
            connection.Open();
            command.CommandTimeout = NotificationTimeout;

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    message = System.Text.ASCIIEncoding.ASCII.GetString((byte[])reader.GetValue(13));
                }
            }
        }
    }

    return message;
}