【问题标题】:Threaded Sql Query in C#C# 中的线程化 Sql 查询
【发布时间】:2014-03-18 11:50:37
【问题描述】:

我已搜索存档但找不到合适的条目。抱歉,如果存在。

我正在使用 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 必须在最后对主线程可用。

提前致谢

【问题讨论】:

  • @SATSON 使用不同的线程不会停止远程服务器上的查询

标签: c# sql sql-server multithreading


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    恐怕IDbDataAdapterDataTable.Load 没有异步或可取消的API,所以你唯一的方法是像https://stackoverflow.com/a/2108944/307976 那样在ThreadPool 线程中完成这项工作,如果你想取消它就忘了它.

    【讨论】:

    • 取消服务端命令与客户端线程无关
    • 想知道使用 SqlCommand.Cancel 吗? SqlCommand.Cancel 是否停止远程端的查询?我认为可以以某种方式做到这一点。用户可以在 Management Studio 和 Toad For SqlServer 中停止查询
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      SqlCommand.Cancel 可能在这里有用。

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

      此链接中的 Worker 类有 2 个您应该注意的方法。 DoWork,您可以在其中调用您的 sql 查询,另一个是 RequestStop,您可以在其中调用您的 SqlCommand.Cancel,这应该会停止您在服务器端执行查询。 RequestStop 方法可以由用户事件调用,例如单击按钮,这反过来将停止执行查询。

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        试试这样的...

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-16
          • 2021-12-08
          相关资源
          最近更新 更多