C#中的线程Sql查询

时间:2014-03-18 11:50:37

标签: c# sql sql-server multithreading

我搜索了档案,但无法找到合适的条目。抱歉,如果存在。

即时使用vs2008,.NET 3.5,MS-SQL2008

我的代码很简单;

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查询的同一个线程中做那些。

上述代码的最佳和最简单的线程方法应该是什么?有人可以回复一段代码吗?注意; DataTable dt必须最后可用于主线程。

提前致谢

5 个答案:

答案 0 :(得分:3)

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

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);
}

答案 1 :(得分:1)

我担心IDbDataAdapterDataTable.Load没有异步或可取消的API,所以你唯一的办法就是在像https://stackoverflow.com/a/2108944/307976这样的ThreadPool线程中完成工作而忘记它如果你想取消它。

答案 2 :(得分:0)

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

回到UI线程很简单,如果回调没有自动回到那里,只需在某些控件上使用Invoke,并且该代码将在UI线程上尽早处理

您可以致电SqlCommand.Cancel尝试取消查询,这应该可以解决。如果它没有,那么您唯一的另一个选择是创建另一个SqlConnection和另一个SqlCommand,并通过SQL终止其他连接。

答案 3 :(得分:0)

SqlCommand.Cancel可能在这里有用。

创建链接here中给出的类。此链接提供了一个很好的示例,说明如何启动线程并正常终止它。

此链接中的班级Worker有两种方法,您应该注意这些方法。 DoWork您可以在其中调用您的SQL查询,另一个是RequestStop,您可以在其中调用SqlCommand.Cancel,这将阻止您在服务器端执行查询。 RequestStop方法可以通过用户事件调用,例如按钮点击,这反过来将停止执行查询。

希望这有帮助。

答案 4 :(得分:0)

尝试这样的事情......

    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();