如何使用应用程序强制我的数据集重新连接并防止超时错误?

发布于 2024-08-09 18:21:55 字数 1945 浏览 1 评论 0原文

简单问题

在继续使用 DataSet 对象之前,我可以使用什么命令来使 DataSet 刷新它与 SQL Server 的连接? 我正在 .Net 2.0 中使用 C#


相同问题的更长版本,具体内容

我有一个数据库应用程序,该应用程序通常在手动启动的操作之间运行几个小时。当长时间(> 1小时)返回应用程序并单击按钮时,它将抛出 System.Data.SqlClient.SqlException 并显示错误消息

超时已过。操作完成前超时时间已过或服务器未响应

我想这里有几个选项:

  • 增加超时,
  • 强制应用程序在执行操作后关闭,确保应用程序始终在用户操作时重新启动想要它。
  • 在执行每个操作之前测试连接的健康状况。

我更喜欢后者,但我不知道在哪里可以调用或测试连接。我正在使用 Visual Studio 拖放构建我的数据集,创建一个实例。填充表格并将数据集传递到另一个表单。当加载其他表单时,才会引发异常,但前提是应用程序闲置数小时。

我尚未设法在调试模式下复制此内容,但我认为该异常可能是由下面的子表单构造函数的 _dsDistrib.tblReport.DefaultView.Sort 行引发的。

那么,在尝试使用 DataSet 之前,如何确保该 DataSet 具有活动连接,或强制建立新连接?

主窗体相关代码

    public frmMain(string[] args)
    {
        InitializeComponent();
        _dsDistrib = new dsDistrib();
        taDistrib = new ReportShunt.dsDistribTableAdapters.tblDistribTableAdapter();
        taDistrib.Fill(_dsDistrib.tblDistrib);
    } 

    private void btnManage_Click(object sender, EventArgs e)
    {
        new frmManageDespatch(_dsDistrib,taDistrib).ShowDialog();
    }

子窗体的构造函数

    public frmManageDespatch(dsDistrib ds, dsDistribTableAdapters.tblDistribTableAdapter taDis)
    {
        InitializeComponent();

        _dsDistrib = ds;
        taDistrib = taDis;

        _dsDistrib.tblReport.DefaultView.Sort = "tblReportId";

        dtUsers = (dsDistrib.tblUserDataTable)_dsDistrib.tblUser.Copy();

        cboReport.DataSource = _dsDistrib.tblReport;
        cboReport.DisplayMember = _dsDistrib.tblReport.ReportNameColumn.ColumnName;
        cboReport.ValueMember = _dsDistrib.tblReport.tblReportIdColumn.ColumnName;

        lbxUserSelection.DataSource = dtUsers;
        lbxUserSelection.DisplayMember = dtUsers.OutputFolderColumn.ColumnName;
        lbxUserSelection.ValueMember = dtUsers.tblUserIdColumn.ColumnName;

    }

Brief question

What command can I use to make my DataSet refresh it's connection to the SQL Server before I go on to work with the DataSet object?
I'm working with C# in .Net 2.0


Much longer version of the same question with specifics

I have a database application that is often left running for several hours between manually instigated operations. When returning to the application after a long period (> 1 hour) and clicking a button it will throw a System.Data.SqlClient.SqlException with the error message

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding

I figure I have a few options here:

  • increase the timeout
  • force the application to close after it has performed it's operation ensuring that the app is always started afresh when a user wants it.
  • test the health of the connection before performing each operation.

My preference would be the latter but I don't know where a connection can be invoked or tested. I'm using Visual Studio to drag-drop build my DataSet, creating an instance. Filling tables and passing the dataset to another form. It is when loading this other form that the exception is thrown, but only if the application is left idle for hours.

I have not managed to replicate this in debug mode as yet, but I think the exception is likely being thrown by the _dsDistrib.tblReport.DefaultView.Sortline of the child forms constructor below.

So how can I make sure this DataSet has an active connection, or force a new connection, before I try to use the DataSet?

Relevant code of the main form

    public frmMain(string[] args)
    {
        InitializeComponent();
        _dsDistrib = new dsDistrib();
        taDistrib = new ReportShunt.dsDistribTableAdapters.tblDistribTableAdapter();
        taDistrib.Fill(_dsDistrib.tblDistrib);
    } 

    private void btnManage_Click(object sender, EventArgs e)
    {
        new frmManageDespatch(_dsDistrib,taDistrib).ShowDialog();
    }

Constructor of the child form

    public frmManageDespatch(dsDistrib ds, dsDistribTableAdapters.tblDistribTableAdapter taDis)
    {
        InitializeComponent();

        _dsDistrib = ds;
        taDistrib = taDis;

        _dsDistrib.tblReport.DefaultView.Sort = "tblReportId";

        dtUsers = (dsDistrib.tblUserDataTable)_dsDistrib.tblUser.Copy();

        cboReport.DataSource = _dsDistrib.tblReport;
        cboReport.DisplayMember = _dsDistrib.tblReport.ReportNameColumn.ColumnName;
        cboReport.ValueMember = _dsDistrib.tblReport.tblReportIdColumn.ColumnName;

        lbxUserSelection.DataSource = dtUsers;
        lbxUserSelection.DisplayMember = dtUsers.OutputFolderColumn.ColumnName;
        lbxUserSelection.ValueMember = dtUsers.tblUserIdColumn.ColumnName;

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

软糯酥胸 2024-08-16 18:21:55

编辑:根据您的评论,我现在猜测 taDistrib 是一个 SqlDataAdapter,它是从名为 ReportShunt 的库中填充的。库负责打开连接。

假设表适配器有一个选择命令,您可以像这样关闭连接。表适配器通常会在与数据库对话之前自行打开它:

private void btnManage_Click(object sender, EventArgs e)
{
    taDistrib.SelectCommand.Connection.Close();
    new frmManageDespatch(_dsDistrib,taDistrib).ShowDialog();
}

您还可以获取一个全新的连接:

private void btnManage_Click(object sender, EventArgs e)
{
    var localDsDistrib = new dsDistrib();
    var localTaDistrib = new ReportShunt.dsDistribTableAdapters.
         tblDistribTableAdapter();
    taDistrib.Fill(dsDistrib.tblDistrib);
    new frmManageDespatch(localDsDistrib,localTaDistrib).ShowDialog();
}

更好的是,仅在您实际使用它执行某些操作时才保持连接打开。连接被缓存并重新打开它们根本没有任何开销。 (我们对数百万个请求进行了测量,但没有发现明显的差异。)

EDIT: from your comment, I'm now guessing taDistrib is a SqlDataAdapter that is populated from a library called ReportShunt. The library is responsible for opening the connection.

Assuming that the table adapter has a select command, you could close the connection like. The table adapter would normally open it itself, before it talks to the database:

private void btnManage_Click(object sender, EventArgs e)
{
    taDistrib.SelectCommand.Connection.Close();
    new frmManageDespatch(_dsDistrib,taDistrib).ShowDialog();
}

You can also grab an entirely new connection:

private void btnManage_Click(object sender, EventArgs e)
{
    var localDsDistrib = new dsDistrib();
    var localTaDistrib = new ReportShunt.dsDistribTableAdapters.
         tblDistribTableAdapter();
    taDistrib.Fill(dsDistrib.tblDistrib);
    new frmManageDespatch(localDsDistrib,localTaDistrib).ShowDialog();
}

Better yet, only keep the connection open when you're actually doing something with it. Connections get cached and reopening them has no overhead at all. (We measured it with millions of request, and couldn't find a noticaeble difference.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文