【问题标题】:How to make oledb query asychronous如何使oledb查询异步
【发布时间】:2019-07-04 04:23:12
【问题描述】:

我遇到了这个查询的问题,它需要很长时间才能运行并且正在超时。我想尝试使其异步,但我找不到一个与我正在尝试做的事情接近的好例子。

以下是我尝试过的,它启动但什么也没做。这是在 WinForm 项目中。

namespace access_db_csharp
{
    public partial class Form1 : Form
    {
        string SQL = "";
        public Form1()
        {
            InitializeComponent();
            textBox1.Text = "Select Project, Request, Release, TestName, AssignmentNumber, Formulation, Container, Closure FROM tblWtLossBottDropResults";
            textBox2.Text = "Where Container LIKE '%2700-305%'";
            dataGridView1.Focus();
        }
        OleDbConnection con=new OleDbConnection ();
        OleDbCommand cmd=new OleDbCommand ();
        string connectionstring = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=K:\R&D Dept\Development Lab\DLab Databases and Add Ins\DLab Results Database\DLab Results Individual Tables.accdb;Jet OLEDB:Database Password='roscoe'";

        private async void button1_Click(object sender, EventArgs e)
        {
            Task<DataTable> task = new Task<DataTable>(RunQuery);
            task.Start();

        }

        private DataTable RunQuery()
        {
            if (checkBox1.Checked == true)
            {
                SQL = textBox1.Text + " " + textBox2.Text;
            }
            else
            {
                SQL = textBox1.Text;
            }
            OleDbConnection con = new OleDbConnection(connectionstring);
            OleDbCommand cmd = new OleDbCommand(SQL, con);
            con.Open();
            cmd.CommandType = CommandType.Text;
            OleDbDataAdapter da = new OleDbDataAdapter(cmd);
            DataTable tblWtLossBottDropResults = new DataTable();
            da.Fill(tblWtLossBottDropResults);
            dataGridView1.DataSource = tblWtLossBottDropResults;

            //dataGridView1.ColumnCount = 17;
            dataGridView1.Columns[0].Name = "Project";
            dataGridView1.Columns[1].Name = "Request";
            dataGridView1.Columns[2].Name = "Release";
            dataGridView1.Columns[3].Name = "TestName";
            dataGridView1.Columns[4].Name = "AssignmentNumber";
            dataGridView1.Columns[5].Name = "Formulation";
            dataGridView1.Columns[6].Name = "Container";
            dataGridView1.Columns[7].Name = "Closure";

            MessageBox.Show("Done");
            int numRows = dataGridView1.RowCount;
            label4.Text = "Rows Returned: " + numRows.ToString();

            return tblWtLossBottDropResults;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            con.ConnectionString = connectionstring;
            con.Open();
        }
    }
}

理想情况下,我想从查询中获取数据并将其加载到 datagridview 表中。

【问题讨论】:

  • 是什么让你认为异步不会超时?
  • 你在哪里看到过使用Task构造函数和Task.Start的推荐?
  • 我在你的视频上看到了它。如果这不是正确的方法,你能告诉我什么是正确的吗?它可能仍会超时,但至少 UI 会响应。
  • 我会看看,但真的希望有人可以帮助我修复我的代码。我一直在阅读有关此的各种内容并尝试各种事情。我找不到任何使代码像我一样异步的示例。

标签: c#-5.0


【解决方案1】:

有几件事你应该改变:

1. You should not mix UI and non-UI code.
2. You should keep your connection open for the shortest amount of time.

因为 OleDb 提供程序没有异步 API,所以您的数据库代码将是同步的:

private DataTable RunQuery(string commandText)
{
    using (var connection = new OleDbConnection(connectionstring))
    {
        using (var command = connection.CreateCommand())
        {
            command.CommandType = CommandType.Text;
            command.CommandText = commandText;

            using (var dataAdapter = new OleDbDataAdapter(command))
            {
                connection.Open();

                var dataTable = new DataTable();
                dataAdapter.Fill(dataTable);

                return dataTable;
            }
        }
    }
}

因为它是一个 Windows 窗体应用程序,您可以使用 Task.Run 将工作卸载到线程池并释放 UI 线程:

private async void button1_Click(object sender, EventArgs e)
{
    var commandText = checkBox1.Checked
        ? textBox1.Text + " " + textBox2.Text
        : textBox1.Text;

    var dataTable = await Task.Run(() => RunQuery(commandText));

    /* This should be set on the designer or on the constructor
    //dataGridView1.ColumnCount = 17;
    dataGridView1.Columns[0].Name = "Project";
    dataGridView1.Columns[1].Name = "Request";
    dataGridView1.Columns[2].Name = "Release";
    dataGridView1.Columns[3].Name = "TestName";
    dataGridView1.Columns[4].Name = "AssignmentNumber";
    dataGridView1.Columns[5].Name = "Formulation";
    dataGridView1.Columns[6].Name = "Container";
    dataGridView1.Columns[7].Name = "Closure";
    */

    dataGridView1.DataSource = dataTable;
    MessageBox.Show("Done");
    int numRows = dataGridView1.RowCount;
    label4.Text = "Rows Returned: " + numRows.ToString();
}

【讨论】:

  • 感谢您的指导;感谢这些信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
相关资源
最近更新 更多