Share via


SqlCommand.BeginExecuteXmlReader 方法

定义

重载

BeginExecuteXmlReader()

启动此 SqlCommand 描述的 Transact-SQL 语句或存储过程的异步执行,并将结果作为 XmlReader 对象返回。

BeginExecuteXmlReader(AsyncCallback, Object)

通过使用回调过程,启动此 SqlCommand 描述的 Transact-SQL 语句或存储过程的异步执行,并将结果作为 XmlReader 对象返回。

BeginExecuteXmlReader()

启动此 SqlCommand 描述的 Transact-SQL 语句或存储过程的异步执行,并将结果作为 XmlReader 对象返回。

public:
 IAsyncResult ^ BeginExecuteXmlReader();
public IAsyncResult BeginExecuteXmlReader ();
member this.BeginExecuteXmlReader : unit -> IAsyncResult
Public Function BeginExecuteXmlReader () As IAsyncResult

返回

一个 IAsyncResult ,可用于轮询或等待结果,或两者兼而有之;调用时也需要此值EndExecuteXmlReader ,它返回单个 XML 值。

例外

SqlDbType当 设置为 StreamValue,使用 BinaryVarBinary 以外的 。 有关流式处理的详细信息,请参阅 SqlClient 流支持

- 或 -

SqlDbType设置为 时ValueTextReader ,使用了 CharNCharNVarCharVarCharXml 以外的其他项。

-或-

SqlDbType设置为 时ValueXmlReader ,使用了 Xml 以外的 。

执行命令文本时出现的任何错误。

- 或 -

流式处理操作期间发生了超时。 有关流式处理的详细信息,请参阅 SqlClient 流支持

流式处理操作期间关闭或删除了 SqlConnection。 有关流式处理的详细信息,请参阅 SqlClient 流支持

- or -

<xref data-throw-if-not-resolved="true" uid="Microssoft.Data.SqlClient.SqlCommand.EnableOptimizedParameterBinding"></xref>
is set to true and a parameter with direction Output or InputOutput has been added to the <xref data-throw-if-not-resolved="true" uid="Microsoft.Data.SqlClient.SqlCommand.Parameters"></xref> collection.

在流式处理操作期间, XmlReaderTextReader 对象中Stream发生错误。 有关流式处理的详细信息,请参阅 SqlClient 流支持

StreamXmlReader流式处理操作期间, 或 TextReader 对象已关闭。 有关流式处理的详细信息,请参阅 SqlClient 流支持

示例

以下控制台应用程序启动异步检索 XML 数据的过程。 在等待结果时,此简单应用程序位于循环中,调查 IsCompleted 属性值。 该过程完成后,代码将检索 XML 并显示其内容。

[!code-csharp[SqlCommand_BeginExecuteXmlReader#1] ( (~/../sqlclient/doc/samples/SqlCommand_BeginExecuteXmlReader.cs) ]

注解

方法 BeginExecuteXmlReader 启动异步执行 Transact-SQL 语句的过程,该语句将行作为 XML 返回,以便其他任务可以在语句执行时并发运行。 语句完成后,开发人员必须调用 EndExecuteXmlReader 方法来完成操作并检索命令返回的 XML。 方法 BeginExecuteXmlReader 会立即返回,但在代码执行相应的 EndExecuteXmlReader 方法调用之前,它不得执行针对同 SqlCommand 一对象启动同步或异步执行的任何其他调用。 EndExecuteXmlReader在命令执行完成之前调用 会导致SqlCommand对象阻塞,直到执行完成。

属性 CommandText 通常指定具有有效 FOR XML 子句的 Transact-SQL 语句。 但是, CommandText 也可以指定返回包含有效 XML 的数据的 ntext 语句。

典型 BeginExecuteXmlReader 查询的格式可以设置为以下 C# 示例中的格式:

SqlCommand command = new SqlCommand("SELECT ContactID, FirstName, LastName FROM dbo.Contact FOR XML AUTO, XMLDATA", SqlConn);

此方法还可用于检索单行、单列结果集。 在这种情况下,如果返回了多行,该方法 EndExecuteXmlReader 会将 XmlReader 附加到第一行的值,并放弃结果集的其余部分。

MARS) 功能 (多个活动结果集允许多个操作使用同一连接。

请注意,命令文本和参数以同步方式发送到服务器。 如果发送了大型命令或多个参数,此方法可能会在写入期间阻止。 发送命令后,方法会立即返回,无需等待服务器的答案,即读取是异步的。 虽然命令执行是异步的,但值提取仍然是同步的。

由于此重载不支持回调过程,因此开发人员需要使用 方法返回的 的 IAsyncResult 属性轮询以确定命令是否已完成IsCompleted;或者使用AsyncWaitHandle返回IAsyncResult的 的 属性等待一个或多个命令完成。BeginExecuteXmlReader

如果使用 ExecuteReaderBeginExecuteReader 访问 XML 数据,SQL Server将返回长度超过 2,033 个字符的任何 XML 结果,每行 2,033 个字符。 若要避免此行为,请使用 ExecuteXmlReaderBeginExecuteXmlReader 读取 FOR XML 查询。

此方法忽略 CommandTimeout 属性。

适用于

BeginExecuteXmlReader(AsyncCallback, Object)

通过使用回调过程,启动此 SqlCommand 描述的 Transact-SQL 语句或存储过程的异步执行,并将结果作为 XmlReader 对象返回。

public:
 IAsyncResult ^ BeginExecuteXmlReader(AsyncCallback ^ callback, System::Object ^ stateObject);
public IAsyncResult BeginExecuteXmlReader (AsyncCallback callback, object stateObject);
member this.BeginExecuteXmlReader : AsyncCallback * obj -> IAsyncResult
Public Function BeginExecuteXmlReader (callback As AsyncCallback, stateObject As Object) As IAsyncResult

参数

callback
AsyncCallback

命令执行完成时调用的 AsyncCallback 委托。 通过nullNothing ( Microsoft Visual Basic) 中指示不需要回调。

stateObject
Object

传递到回调过程的用户定义的状态对象。 使用 AsyncState 属性从回调过程内检索此对象。

返回

可用于轮询和/或等待结果的 IAsyncResult;当调用 EndExecuteXmlReader(IAsyncResult) 时,也需要该值,用于将命令的结果作为 XML 返回。

例外

SqlDbType当 设置为 StreamValue,使用 BinaryVarBinary 以外的 。 有关流式处理的详细信息,请参阅 SqlClient 流支持

- 或 -

SqlDbType设置为 时ValueTextReader ,使用了 CharNCharNVarCharVarCharXml 以外的其他项。

-或-

SqlDbType设置为 时ValueXmlReader ,使用了 Xml 以外的 。

执行命令文本时出现的任何错误。

- 或 -

流式处理操作期间发生了超时。 有关流式处理的详细信息,请参阅 SqlClient 流支持

流式处理操作期间关闭或删除了 SqlConnection。 有关流式处理的详细信息,请参阅 SqlClient 流支持

- or -

<xref data-throw-if-not-resolved="true" uid="Microssoft.Data.SqlClient.SqlCommand.EnableOptimizedParameterBinding"></xref>
is set to true and a parameter with direction Output or InputOutput has been added to the <xref data-throw-if-not-resolved="true" uid="Microsoft.Data.SqlClient.SqlCommand.Parameters"></xref> collection.

在流式处理操作期间, XmlReaderTextReader 对象中Stream发生错误。 有关流式处理的详细信息,请参阅 SqlClient 流支持

StreamXmlReader流式处理操作期间, 或 TextReader 对象已关闭。 有关流式处理的详细信息,请参阅 SqlClient 流支持

示例

以下 Windows 应用程序演示如何使用 BeginExecuteXmlReader 方法,以执行包含几秒钟延迟(模拟长时间运行的命令)的 Transact-SQL 语句。 此示例将正在执行 SqlCommand 的对象作为 stateObject 参数进行传递-这样做使得从回调过程中检索 SqlCommand 对象变得简单,以便代码可以调用 EndExecuteXmlReader 对应于对 的初始调用 BeginExecuteXmlReader的方法。

此示例演示了许多重要的技术。 这包括从单独的线程调用与窗体交互的方法。 此外,此示例演示了如何阻止用户多次同时执行命令,以及如何在调用回调过程之前确保窗体不会关闭。

若要设置此示例,请创建新的 Windows 应用程序。 将 Button 控件、 ListBox 控件和 Label 控件放在窗体上, (接受每个控件的默认名称) 。 将以下代码添加到窗体的 类,根据环境需要修改连接字符串。

// <Snippet1>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Data.SqlClient;
using System.Xml;

namespace Microsoft.AdoDotNet.CodeSamples
{
    public partial class Form1 : Form
    {
        // Hook up the form's Load event handler and then add 
        // this code to the form's class:
        // You need these delegates in order to display text from a thread
        // other than the form's thread. See the HandleCallback
        // procedure for more information.
        private delegate void DisplayInfoDelegate(string Text);
        private delegate void DisplayReaderDelegate(XmlReader reader);

        private bool isExecuting;

        // This example maintains the connection object 
        // externally, so that it is available for closing.
        private SqlConnection connection;

        public Form1()
        {
            InitializeComponent();
        }

        private string GetConnectionString()
        {
            // To avoid storing the connection string in your code, 
            // you can retrieve it from a configuration file. 

            return "Data Source=(local);Integrated Security=true;" +
            "Initial Catalog=AdventureWorks";
        }

        private void DisplayStatus(string Text)
        {
            this.label1.Text = Text;
        }

        private void ClearProductInfo()
        {
            // Clear the list box.
            this.listBox1.Items.Clear();
        }

        private void DisplayProductInfo(XmlReader reader)
        {
            // Display the data within the reader.
            while (reader.Read())
            {
                // Skip past items that are not from the correct table.
                if (reader.LocalName.ToString() == "Production.Product")
                {
                    this.listBox1.Items.Add(String.Format("{0}: {1:C}",
                        reader["Name"], Convert.ToDecimal(reader["ListPrice"])));
                }
            }
            DisplayStatus("Ready");
        }

        private void Form1_FormClosing(object sender,
            System.Windows.Forms.FormClosingEventArgs e)
        {
            if (isExecuting)
            {
                MessageBox.Show(this, "Cannot close the form until " +
                    "the pending asynchronous command has completed. Please wait...");
                e.Cancel = true;
            }
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            if (isExecuting)
            {
                MessageBox.Show(this,
                    "Already executing. Please wait until the current query " +
                    "has completed.");
            }
            else
            {
                SqlCommand command = null;
                try
                {
                    ClearProductInfo();
                    DisplayStatus("Connecting...");
                    connection = new SqlConnection(GetConnectionString());

                    // To emulate a long-running query, wait for 
                    // a few seconds before working with the data.
                    string commandText =
                        "WAITFOR DELAY '00:00:03';" +
                        "SELECT Name, ListPrice FROM Production.Product " +
                        "WHERE ListPrice < 100 " +
                        "FOR XML AUTO, XMLDATA";

                    command = new SqlCommand(commandText, connection);
                    connection.Open();

                    DisplayStatus("Executing...");
                    isExecuting = true;
                    // Although it is not required that you pass the 
                    // SqlCommand object as the second parameter in the 
                    // BeginExecuteXmlReader call, doing so makes it easier
                    // to call EndExecuteXmlReader in the callback procedure.
                    AsyncCallback callback = new AsyncCallback(HandleCallback);
                    command.BeginExecuteXmlReader(callback, command);

                }
                catch (Exception ex)
                {
                    isExecuting = false;
                    DisplayStatus(string.Format("Ready (last error: {0})", ex.Message));
                    if (connection != null)
                    {
                        connection.Close();
                    }
                }
            }
        }

        private void HandleCallback(IAsyncResult result)
        {
            try
            {
                // Retrieve the original command object, passed
                // to this procedure in the AsyncState property
                // of the IAsyncResult parameter.
                SqlCommand command = (SqlCommand)result.AsyncState;
                XmlReader reader = command.EndExecuteXmlReader(result);

                // You may not interact with the form and its contents
                // from a different thread, and this callback procedure
                // is all but guaranteed to be running from a different thread
                // than the form. 

                // Instead, you must call the procedure from the form's thread.
                // One simple way to accomplish this is to call the Invoke
                // method of the form, which calls the delegate you supply
                // from the form's thread. 
                DisplayReaderDelegate del = new DisplayReaderDelegate(DisplayProductInfo);
                this.Invoke(del, reader);

            }
            catch (Exception ex)
            {
                // Because you are now running code in a separate thread, 
                // if you do not handle the exception here, none of your other
                // code catches the exception. Because none of 
                // your code is on the call stack in this thread, there is nothing
                // higher up the stack to catch the exception if you do not 
                // handle it here. You can either log the exception or 
                // invoke a delegate (as in the non-error case in this 
                // example) to display the error on the form. In no case
                // can you simply display the error without executing a delegate
                // as in the try block here. 

                // You can create the delegate instance as you 
                // invoke it, like this:
                this.Invoke(new DisplayInfoDelegate(DisplayStatus),
                String.Format("Ready(last error: {0}", ex.Message));
            }
            finally
            {
                isExecuting = false;
                if (connection != null)
                {
                    connection.Close();
                }
            }
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.FormClosing += new System.Windows.Forms.
                FormClosingEventHandler(this.Form1_FormClosing);
        }
    }
}
// </Snippet1>

注解

方法 BeginExecuteXmlReader 启动异步执行 Transact-SQL 语句或将行作为 XML 返回的存储过程的过程,以便其他任务可以在语句执行时并发运行。 语句完成后,开发人员必须调用 EndExecuteXmlReader 方法来完成操作并检索请求的 XML 数据。 方法 BeginExecuteXmlReader 会立即返回,但在代码执行相应的 EndExecuteXmlReader 方法调用之前,它不得执行针对同 SqlCommand 一对象启动同步或异步执行的任何其他调用。 EndExecuteXmlReader在命令执行完成之前调用 会导致SqlCommand对象阻塞,直到执行完成。

属性 CommandText 通常指定具有有效 FOR XML 子句的 Transact-SQL 语句。 但是, CommandText 也可以指定返回包含有效 XML 的数据的语句。 此方法还可用于检索单行、单列结果集。 在这种情况下,如果返回了多行,该方法 EndExecuteXmlReader 会将 XmlReader 附加到第一行的值,并放弃结果集的其余部分。

典型 BeginExecuteXmlReader 查询的格式可以设置为以下 C# 示例中的格式:

SqlCommand command = new SqlCommand("SELECT ContactID, FirstName, LastName FROM Contact FOR XML AUTO, XMLDATA", SqlConn);

此方法还可用于检索单行、单列结果集。 在这种情况下,如果返回了多行,该方法 EndExecuteXmlReader 会将 XmlReader 附加到第一行的值,并放弃结果集的其余部分。

MARS) 功能 (多个活动结果集允许多个操作使用同一连接。

参数 callback 允许指定在 AsyncCallback 语句完成时调用的委托。 可以从此委托过程中或应用程序内的任何其他位置调用 EndExecuteXmlReader 方法。 此外,可以传递 参数中的任何 stateObject 对象,并且回调过程可以使用 属性检索此信息 AsyncState

请注意,命令文本和参数以同步方式发送到服务器。 如果发送了大型命令或多个参数,此方法可能会在写入期间阻止。 发送命令后,方法会立即返回,无需等待服务器的答案,即读取是异步的。

在执行操作期间发生的所有错误都会在回调过程中作为异常引发。 必须在回调过程中处理异常,而不是在主应用程序中处理。 有关在回调过程中处理异常的其他信息,请参阅本主题中的示例。

如果使用 ExecuteReaderBeginExecuteReader 访问 XML 数据,SQL Server将返回长度超过 2,033 个字符的任何 XML 结果,每行 2,033 个字符。 若要避免此行为,请使用 ExecuteXmlReaderBeginExecuteXmlReader 读取 FOR XML 查询。

此方法忽略 CommandTimeout 属性。

另请参阅

适用于