c#中的线程Sql查询

本文关键字:Sql 查询 线程 | 更新日期: 2023-09-27 17:50:43

我搜索了存档,但找不到合适的条目。

我使用vs2008, .NET 3.5, MS-SQL2008

My Code is simple;

SqlConnection CONN=new SqlConnection(SomeConnectionString);
CONN.Open();
SqlCommand cmd = CONN.CreateCommand();
cmd.CommandText="SELECT FIELD1,FIELD2,FIELD3 from table1";
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);

所以DataTable dt已经可以使用了。

但是我想让查询被用户停止,因为它可能会持续太长时间等待。因此用户将停止查询,更改参数并重新查询。

我还想在查询执行期间显示查询时间的秒表。

正如预期的那样,我不能在sql查询的同一个线程中做这些。

对于上面的代码,最好和最简单的线程方法应该是什么?谁能给我一段代码吗?请注意;数据表dt必须在结束时对主线程可用。

thanks in advance

c#中的线程Sql查询

如果你想做一个单独的线程并在那里执行命令,你可以尝试下面的代码:

System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(LoadDB));
thread.Start();
//put this command wherever you want
private void LoadDB()
{
SqlConnection CONN=new SqlConnection(SomeConnectionString);
CONN.Open();
SqlCommand cmd = CONN.CreateCommand();
cmd.CommandText="SELECT FIELD1,FIELD2,FIELD3 from table1";
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
}

恐怕IDbDataAdapterDataTable.Load没有异步或可取消的API,所以您唯一的方法是在ThreadPool线程中做这项工作,如https://stackoverflow.com/a/2108944/307976,如果您想取消它,请忘记它。

可以使用SqlCommand.BeginExecuteReader启动异步命令。这允许你处理UI(你的"秒表"),并在异步回调中继续工作。

返回UI线程很简单,如果回调没有自动结束,只需在一些控件上使用Invoke,该代码将在UI线程上尽早处理。

您可以调用SqlCommand.Cancel来尝试取消查询,这应该可以正常工作。如果没有,您唯一的其他选择是创建另一个SqlConnection和另一个SqlCommand,并通过SQL终止other连接。

SqlCommand.Cancel可能在这里有用。

按照这里的链接创建一个类。这个链接提供了一个很好的示例,说明如何优雅地启动和终止线程。

Worker在这个链接有2个方法,你应该注意。DoWork,你可以在其中调用你的sql查询,另一个是RequestStop,你可以在其中调用你的SqlCommand.Cancel,它应该停止你在服务器端执行查询。RequestStop方法可以被用户事件调用,比如按钮点击,然后停止查询的执行。

试试这样做…

    Thread t = new Thread(() => {
        using (SqlConnection con = new SqlConnection(_someConnectionString)) {
            string query = "SELECT FIELD1, FIELD2, FIELD3 FROM table1";
                using (SqlCommand com = new SqlCommand(query, con)) {
                    try {
                       con.Open();
                       using (SqlDataReader reader = com.ExecuteReader()) {
                           if (reader.HasRows) {
                               DataTable dt = new DataTable();
                               dt.Load(reader);
                           }
                       }
                    } catch (Exception ex) {
                        // Anything you want to do with ex
                    } finally {
                        con.Close();
                    }
                }
        }
    });
    t.IsBackground = true;
    t.Start();