Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SqlCommand.StatementCompleted应该在什么时候启动?_C#_.net_Sql Server_Ado.net_Asynchronous - Fatal编程技术网

C# SqlCommand.StatementCompleted应该在什么时候启动?

C# SqlCommand.StatementCompleted应该在什么时候启动?,c#,.net,sql-server,ado.net,asynchronous,C#,.net,Sql Server,Ado.net,Asynchronous,更新我需要澄清我问题中的某些内容吗?我很惊讶地看到我在两周内没有得到任何评价、评论或回答 我正在尝试编写一个简单的winforms应用程序,它执行一个SQL SELECT异步语句。当sql server开始返回结果时,我希望执行一个连接到SqlCommand的StatementCompleted事件的事件处理程序 表单包含两个按钮、一个文本框和一个标签。单击button1时,我创建SqlCommand并连接事件处理程序,然后打开SqlConnection并调用BeginExecuteReade

更新我需要澄清我问题中的某些内容吗?我很惊讶地看到我在两周内没有得到任何评价、评论或回答


我正在尝试编写一个简单的winforms应用程序,它执行一个SQL SELECT异步语句。当sql server开始返回结果时,我希望执行一个连接到SqlCommand的StatementCompleted事件的事件处理程序

表单包含两个按钮、一个文本框和一个标签。单击button1时,我创建SqlCommand并连接事件处理程序,然后打开SqlConnection并调用BeginExecuteReader以启动异步操作。我设置标签以显示命令正在执行

在事件处理程序中,我只需设置标签以显示命令已完成

单击按钮2时,我会更改标签以显示我们正在处理结果。然后调用EndExecuteReader并将其返回值分配给一个新的SqlDataReader,然后对其进行处理

我看到的是,当命令准备就绪时,不会调用事件处理程序。相反,当我的代码处理完EndExecuteReader返回的读取器时,会调用它

我是不是遗漏了什么?我是否误解了活动的预期用途?我试图找到语句completed的一个示例,但我只能找到它的一般描述,没有工作代码。位于的示例使用循环并等待IAsyncResult.IsCompleted属性为true。我希望在属性变为true的同时,StatementCompleted事件会激发

public Form1() {
    InitializeComponent();
}

private IAsyncResult iAsyncResult;
private SqlCommand sqlCommand;

private void statementCompleted(object sender,
                                StatementCompletedEventArgs e) {
    label1.Text = "Statement completed";
}

private void button1_Click(object sender, EventArgs e) {
    var northWindConnection =
        new SqlConnection(
            "Data Source=.\\SqlExpress;Initial Catalog=Northwind;" +
            "Integrated Security=True;" +
            "asynchronous processing=true");
    sqlCommand = new SqlCommand("WAITFOR DELAY '00:00:05';" +
                                " SELECT * FROM [Order Details]",
                                northWindConnection);
    sqlCommand.StatementCompleted += statementCompleted;
    northWindConnection.Open();
    iAsyncResult = sqlCommand.BeginExecuteReader();
    label1.Text = "Executing";
}

private void button2_Click(object sender, EventArgs e) {
    label1.Text = "Not waiting anymore, reading";
    var results = new StringBuilder();
    var reader = sqlCommand.EndExecuteReader(iAsyncResult);
    while (reader.Read()) {
        for (int i = 0; i < reader.FieldCount; i++) {
            results.Append(reader[i].ToString() + "\t");
        }
        results.Append(Environment.NewLine);
    }
    reader.Close();
    sqlCommand.Connection.Close();
    textBox1.Text = results.ToString();
}
public Form1(){
初始化组件();
}
私人IAsyncResult IAsyncResult;
专用SqlCommand-SqlCommand;
私有void语句已完成(对象发送方,
语句完成事件参数(e){
label1.Text=“语句已完成”;
}
私有无效按钮1\u单击(对象发送者,事件参数e){
var Northwind连接=
新SqlConnection(
“数据源=。\\SqlExpress;初始目录=北风;”+
“集成安全性=真;”+
“异步处理=真”);
sqlCommand=newsqlcommand(“waitfordelay'00:00:05';”+
“从[订单详细信息]中选择*”,
北风连接);
sqlCommand.StatementCompleted+=StatementCompleted;
northWindConnection.Open();
iAsyncResult=sqlCommand.BeginExecuteReader();
label1.Text=“正在执行”;
}
私有无效按钮2\u单击(对象发送者,事件参数e){
label1.Text=“不再等待,正在阅读”;
var results=新的StringBuilder();
var reader=sqlCommand.EndExecuteReader(iAsyncResult);
while(reader.Read()){
对于(int i=0;i
为可能遇到此问题的任何人添加此选项,因为几个月前该问题被问及,但没有提供答案


StatementCompleted事件在对SqlCommand应用异步调用模式时没有用处。它确实会被解雇,但只有在调用EndExecuteReader时才会被解雇,这基本上已经太晚了。如果您想实现一个异步调用模式,下面有一个很好的解释。中的示例代码显示了SqlCommand在异步模式下的正确用法。

事件顺序如下:

  • 调用
    SqlCommand.BeginExecuteReader(回调,stateObject)
    将T-SQL发送到SQL Server,命令开始执行
  • 当数据首次可用时,将调用提供给
    BeginExecuteReader()
    AsyncCallback
  • 回调调用
    EndExecuteReader()
    以获取对
    SqlDataReader
    对象的引用
  • 您可以使用
    SqlDataReader
    读取查询结果。这可能是一行,也可能是数百万行。在返回所有请求的数据之前,查询不会完成
  • 对其他结果集(如果有)重复此操作
  • 调用
    语句completed
    事件——但仅当查询/存储过程未使用
    设置NOCOUNT ON

  • 换句话说,
    StatementCompleted
    在T-SQL完全完成时调用,包括所有相关的数据传输。

    我怀疑这种行为的线索是事件的“StatementCompletedEventArgs”参数包含属性“RecordCount”,它是受语句影响的行数。
    MS SqlServer(以及之前的Sybase SqlServer,当时的情况)在实际数据全部发送后,将受影响的行数作为单独的“消息”(松散地使用术语)返回


    另外,请注意:Sql命令可以由多个Sql语句组成,每个Sql语句都会影响多个行,因此会返回多个“受影响的行”。因此,我假设对于给定的SQL命令,事件可能会触发多次;或者根本没有设置时间。没有使用计数。

    感谢您第一个发布答案!调用EndExecuteReader时触发StatementCompleted事件的事实是我在问题中已经提到的。你的回答似乎只是重复了我的发现。是的,它确实会开火,但只能在EndExecuteReader上。是的,这意味着它没有用处。但是,哪里有文件证明StatementCompleted事件在EndExecuteReader之前不会触发?文档仅说明它在“Transact-SQL语句的执行完成时”触发。文档的准确之处在于,它在SQL语句完成时触发,但其触发时间未定义。我注意到.NET4的BeginExecuteReader文档示例代码(请参见答案中的链接)与.NET3.5文档不同