SqlCommand.BeginExecuteReader SqlCommand.BeginExecuteReader SqlCommand.BeginExecuteReader SqlCommand.BeginExecuteReader Method

定義

起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand, and retrieves one or more result sets from the server.

多載

BeginExecuteReader() BeginExecuteReader() BeginExecuteReader() BeginExecuteReader()

起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand, and retrieves one or more result sets from the server.

BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior)

藉由使用其中一個 CommandBehavior 值,起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand using one of the CommandBehavior values.

BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object)

指定回呼程序和狀態資訊時,啟始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並且從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand and retrieves one or more result sets from the server, given a callback procedure and state information.

BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior)

指定回呼程序和狀態資訊時,使用其中一個 CommandBehavior 值,起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand, using one of the CommandBehavior values, and retrieving one or more result sets from the server, given a callback procedure and state information.

BeginExecuteReader() BeginExecuteReader() BeginExecuteReader() BeginExecuteReader()

起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand, and retrieves one or more result sets from the server.

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

傳回

IAsyncResult,可用於輪詢或等待結果 (或兩者);叫用 EndExecuteReader(IAsyncResult) 以傳回可用以擷取所傳回資料列的 SqlDataReader 執行個體時,也需要這個值。An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndExecuteReader(IAsyncResult), which returns a SqlDataReader instance that can be used to retrieve the returned rows.

例外狀況

Value 設為 Stream 時,使用 BinaryVarBinary 以外的 SqlDbTypeA SqlDbType other than Binary or VarBinary was used when Value was set to Stream. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

-或--or-

Value 設為 TextReader 時,使用 CharNCharNVarCharVarCharXml 以外的 SqlDbTypeA SqlDbType other than Char, NChar, NVarChar, VarChar, or Xml was used when Value was set to TextReader.

-或--or-

Value 設定為 XmlReader 時,使用 Xml 以外的 SqlDbTypeA SqlDbType other than Xml was used when Value was set to XmlReader.

執行命令文字時發生的任何錯誤。Any error that occurred while executing the command text.

-或--or-

串流作業期間發生逾時。A timeout occurred during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

定義這個 SqlCommand 之連接的連接字串中未包含名稱/值組 "Asynchronous Processing=true"。The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this SqlCommand.

-或--or-

在串流作業期間已關閉或卸除的 SqlConnectionThe SqlConnection closed or dropped during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間發生錯誤。An error occurred in a Stream, XmlReader or TextReader object during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間已關閉。The Stream, XmlReader or TextReader object was closed during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

範例

下列主控台應用程式會開始以非同步方式抓取資料讀取器的進程。The following console application starts the process of retrieving a data reader asynchronously. 在等候結果時, 這個簡單的應用程式會在迴圈中, 調查IsCompleted屬性值。While waiting for the results, this simple application sits in a loop, investigating the IsCompleted property value. 程式完成後, 程式碼SqlDataReader會抓取並顯示其內容。As soon as the process has completed, the code retrieves the SqlDataReader and displays its contents.

using System.Data.SqlClient;

class Class1
{
    static void Main()
    {
        // This is a simple example that demonstrates the usage of the 
        // BeginExecuteReader functionality
        // The WAITFOR statement simply adds enough time to prove the 
        // asynchronous nature of the command.
        string commandText =
            "WAITFOR DELAY '00:00:03';" +
            "SELECT LastName, FirstName FROM Person.Contact " +
            "WHERE LastName LIKE 'M%'";

        RunCommandAsynchronously(commandText, GetConnectionString());

        Console.WriteLine("Press ENTER to continue.");
        Console.ReadLine();
    }

    private static void RunCommandAsynchronously(
        string commandText, string connectionString)
    {
        // Given command text and connection string, asynchronously execute
        // the specified command against the connection. For this example,
        // the code displays an indicator as it is working, verifying the 
        // asynchronous behavior. 
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            try
            {
                SqlCommand command = new SqlCommand(commandText, connection);

                connection.Open();
                IAsyncResult result = command.BeginExecuteReader();

                // Although it is not necessary, the following code
                // displays a counter in the console window, indicating that 
                // the main thread is not blocked while awaiting the command 
                // results.
                int count = 0;
                while (!result.IsCompleted)
                {
                    count += 1;
                    Console.WriteLine("Waiting ({0})", count);
                    // Wait for 1/10 second, so the counter
                    // does not consume all available resources 
                    // on the main thread.
                    System.Threading.Thread.Sleep(100);
                }

                using (SqlDataReader reader = command.EndExecuteReader(result))
                {
                    DisplayResults(reader);
                }
            }
            catch (SqlException ex)
            {
                Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message);
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            catch (Exception ex)
            {
                // You might want to pass these errors
                // back out to the caller.
                Console.WriteLine("Error: {0}", ex.Message);
            }
        }
    }

    private static void DisplayResults(SqlDataReader reader)
    {
        // Display the data within the reader.
        while (reader.Read())
        {
            // Display all the columns. 
            for (int i = 0; i < reader.FieldCount; i++)
                Console.Write("{0} ", reader.GetValue(i));
            Console.WriteLine();
        }
    }

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

        // If you have not included "Asynchronous Processing=true" in the
        // connection string, the command is not able
        // to execute asynchronously.
        return "Data Source=(local);Integrated Security=true;" +
            "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
    }
}
Imports System.Data.SqlClient

Module Module1
    Sub Main()
        ' This is a simple example that demonstrates the usage of the 
        ' BeginExecuteReader functionality.
        ' The WAITFOR statement simply adds enough time to prove the 
        ' asynchronous nature of the command.
        Dim commandText As String = _
         "WAITFOR DELAY '00:00:03';" & _
         "SELECT LastName, FirstName FROM Person.Contact " & _
         "WHERE LastName LIKE 'M%'"

        RunCommandAsynchronously(commandText, GetConnectionString())

        Console.WriteLine("Press ENTER to continue.")
        Console.ReadLine()
    End Sub

    Private Sub RunCommandAsynchronously( _
     ByVal commandText As String, ByVal connectionString As String)

        ' Given command text and connection string, asynchronously execute
        ' the specified command against the connection. For this example,
        ' the code displays an indicator as it is working, verifying the 
        ' asynchronous behavior. 
        Using connection As New SqlConnection(connectionString)
            Try
                Dim command As New SqlCommand(commandText, connection)

                connection.Open()
                Dim result As IAsyncResult = command.BeginExecuteReader()

                ' Although it is not necessary, the following procedure
                ' displays a counter in the console window, indicating that 
                ' the main thread is not blocked while awaiting the command 
                ' results.
                Dim count As Integer
                While Not result.IsCompleted
                    count += 1
                    Console.WriteLine("Waiting ({0})", count)
                    ' Wait for 1/10 second, so the counter
                    ' does not consume all available resources 
                    ' on the main thread.
                    Threading.Thread.Sleep(100)
                End While

                ' Once the IAsyncResult object signals that it is done
                ' waiting for results, you can retrieve the results.
                Using reader As SqlDataReader = command.EndExecuteReader(result)
                    DisplayResults(reader)
                End Using
            Catch ex As SqlException
                Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message)
            Catch ex As InvalidOperationException
                Console.WriteLine("Error: {0}", ex.Message)
            Catch ex As Exception
                ' You might want to pass these errors
                ' back out to the caller.
                Console.WriteLine("Error: {0}", ex.Message)
            End Try
        End Using
    End Sub

    Private Sub DisplayResults(ByVal reader As SqlDataReader)
        ' Display the data within the reader.
        While reader.Read()
            ' Display all the columns.
            For i As Integer = 0 To reader.FieldCount - 1
                Console.Write("{0} ", reader.GetValue(i))
            Next
            Console.WriteLine()
        End While
    End Sub

    Private Function GetConnectionString() As String
        ' To avoid storing the connection string in your code, 
        ' you can retrieve it from a configuration file. 

        ' If you have not included "Asynchronous Processing=true" in the
        ' connection string, the command is not able
        ' to execute asynchronously.
        Return "Data Source=(local);Integrated Security=true;" & _
          "Initial Catalog=AdventureWorks; Asynchronous Processing=true"
    End Function
End Module

備註

BeginExecuteReader方法會啟動以非同步方式執行 transact-sql 語句或預存程式以傳回資料列的程式, 以便在執行語句時, 同時執行其他工作。The BeginExecuteReader method starts the process of asynchronously executing a Transact-SQL statement or stored procedure that returns rows, so that other tasks can run concurrently while the statement is executing. 當語句完成時, 開發人員必須呼叫EndExecuteReader方法來完成作業, 並取出命令所傳回的。 SqlDataReaderWhen the statement has completed, developers must call the EndExecuteReader method to finish the operation and retrieve the SqlDataReader returned by the command. 方法會立即傳回, 但在程式碼執行對應EndExecuteReader的方法呼叫之前, 它不能執行任何其他對相同SqlCommand物件啟動同步或非同步執行的呼叫。 BeginExecuteReaderThe BeginExecuteReader method returns immediately, but until the code executes the corresponding EndExecuteReader method call, it must not execute any other calls that start a synchronous or asynchronous execution against the same SqlCommand object. 在命令EndExecuteReader執行完成之前呼叫, SqlCommand會導致物件封鎖, 直到執行完成為止。Calling the EndExecuteReader before the command's execution is completed causes the SqlCommand object to block until the execution is finished.

請注意, 命令文字和參數會以同步方式傳送到伺服器。Note that the command text and parameters are sent to the server synchronously. 如果傳送的是大型命令或多個參數, 這個方法可能會在寫入期間封鎖。If a large command or many parameters are sent, this method may block during writes. 傳送命令之後, 方法會立即傳回, 而不會等候伺服器的回應, 也就是非同步讀取。After the command is sent, the method returns immediately without waiting for an answer from the server--that is, reads are asynchronous. 雖然命令執行是非同步, 但值提取仍然是同步的。Although command execution is asynchronous, value fetching is still synchronous. 這表示如果需要更Read多資料, 而且基礎網路的讀取作業區塊, 則的呼叫可能會封鎖。This means that calls to Read may block if more data is required and the underlying network's read operation blocks.

因為此多載不支援回呼程式, 所以開發人員必須輪詢以判斷命令是否已完成, 使用IsCompleted BeginExecuteReader方法所傳回之的IAsyncResult屬性, 或等候完成使用AsyncWaitHandle 傳回IAsyncResult之的屬性的一或多個命令。Because this overload does not support a callback procedure, developers must either poll to determine whether the command has completed, using the IsCompleted property of the IAsyncResult returned by the BeginExecuteReader method; or wait for the completion of one or more commands using the AsyncWaitHandle property of the returned IAsyncResult.

如果您使用ExecuteReaderBeginExecuteReader來存取 XML 資料, SQL Server 會傳回超過2033個字元的任何 xml 結果, 其長度為每個2033個字元的多個資料列。If you use ExecuteReader or BeginExecuteReader to access XML data, SQL Server will return any XML results greater than 2,033 characters in length in multiple rows of 2,033 characters each. 若要避免此行為, ExecuteXmlReaderBeginExecuteXmlReader使用或來讀取 FOR XML 查詢。To avoid this behavior, use ExecuteXmlReader or BeginExecuteXmlReader to read FOR XML queries.

另請參閱

BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior) BeginExecuteReader(CommandBehavior)

藉由使用其中一個 CommandBehavior 值,起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand using one of the CommandBehavior values.

public:
 IAsyncResult ^ BeginExecuteReader(System::Data::CommandBehavior behavior);
public IAsyncResult BeginExecuteReader (System.Data.CommandBehavior behavior);
member this.BeginExecuteReader : System.Data.CommandBehavior -> IAsyncResult
Public Function BeginExecuteReader (behavior As CommandBehavior) As IAsyncResult

參數

behavior
CommandBehavior CommandBehavior CommandBehavior CommandBehavior

其中一個 CommandBehavior 值,表示陳述式執行和資料擷取的選項。One of the CommandBehavior values, indicating options for statement execution and data retrieval.

傳回

IAsyncResult,可用於輪詢或等待結果 (或兩者);叫用 EndExecuteReader(IAsyncResult) (會傳回可用以擷取所傳回資料列的 SqlDataReader 執行個體) 時,也需要這個值。An IAsyncResult that can be used to poll, wait for results, or both; this value is also needed when invoking EndExecuteReader(IAsyncResult), which returns a SqlDataReader instance that can be used to retrieve the returned rows.

例外狀況

Value 設為 Stream 時,使用 BinaryVarBinary 以外的 SqlDbTypeA SqlDbType other than Binary or VarBinary was used when Value was set to Stream. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

-或--or-

Value 設為 TextReader 時,使用 CharNCharNVarCharVarCharXml 以外的 SqlDbTypeA SqlDbType other than Char, NChar, NVarChar, VarChar, or Xml was used when Value was set to TextReader.

-或--or-

Value 設定為 XmlReader 時,使用 Xml 以外的 SqlDbTypeA SqlDbType other than Xml was used when Value was set to XmlReader.

執行命令文字時發生的任何錯誤。Any error that occurred while executing the command text.

-或--or-

串流作業期間發生逾時。A timeout occurred during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

定義這個 SqlCommand 之連接的連接字串中未包含名稱/值組 "Asynchronous Processing=true"。The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this SqlCommand.

-或--or-

在串流作業期間已關閉或卸除的 SqlConnectionThe SqlConnection closed or dropped during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間發生錯誤。An error occurred in a Stream, XmlReader or TextReader object during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間已關閉。The Stream, XmlReader or TextReader object was closed during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

範例

下列主控台應用程式會開始以非同步方式抓取資料讀取器的進程。The following console application starts the process of retrieving a data reader asynchronously. 在等候結果時, 這個簡單的應用程式會在迴圈中, 調查IsCompleted屬性值。While waiting for the results, this simple application sits in a loop, investigating the IsCompleted property value. 程式完成後, 程式碼SqlDataReader會抓取並顯示其內容。Once the process has completed, the code retrieves the SqlDataReader and displays its contents.

這個範例也會在CommandBehavior.CloseConnection行為CommandBehavior.SingleRow參數中傳遞和值, 導致在關閉傳回SqlDataReader的時關閉連接, 並針對單一資料列結果優化。This example also passes the CommandBehavior.CloseConnection and CommandBehavior.SingleRow values in the behavior parameter, causing the connection to be closed with the returned SqlDataReader is closed, and to optimize for a single row result.

using System.Data.SqlClient;
class Class1
{
    static void Main()
    {
        // This example is not terribly useful, but it proves a point.
        // The WAITFOR statement simply adds enough time to prove the 
        // asynchronous nature of the command.
        string commandText = "WAITFOR DELAY '00:00:03';" +
            "SELECT ProductID, Name FROM Production.Product WHERE ListPrice < 100";

        RunCommandAsynchronously(commandText, GetConnectionString());

        Console.WriteLine("Press ENTER to continue.");
        Console.ReadLine();
    }

    private static void RunCommandAsynchronously(
        string commandText, string connectionString)
    {
        // Given command text and connection string, asynchronously execute
        // the specified command against the connection. For this example,
        // the code displays an indicator as it is working, verifying the 
        // asynchronous behavior. 

        try
        {
            // The code does not need to handle closing the connection explicitly--
            // the use of the CommandBehavior.CloseConnection option takes care
            // of that for you. 
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand command = new SqlCommand(commandText, connection);

            connection.Open();
            IAsyncResult result = command.BeginExecuteReader(
                CommandBehavior.CloseConnection);

            // Although it is not necessary, the following code
            // displays a counter in the console window, indicating that 
            // the main thread is not blocked while awaiting the command 
            // results.
            int count = 0;
            while (!result.IsCompleted)
            {
                Console.WriteLine("Waiting ({0})", count++);
                // Wait for 1/10 second, so the counter
                // does not consume all available resources 
                // on the main thread.
                System.Threading.Thread.Sleep(100);
            }

            using (SqlDataReader reader = command.EndExecuteReader(result))
            {
                DisplayResults(reader);
            }
        }
        catch (SqlException ex)
        {
            Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine("Error: {0}", ex.Message);
        }
        catch (Exception ex)
        {
            // You might want to pass these errors
            // back out to the caller.
            Console.WriteLine("Error: {0}", ex.Message);
        }
    }

    private static void DisplayResults(SqlDataReader reader)
    {
        // Display the data within the reader.
        while (reader.Read())
        {
            // Display all the columns. 
            for (int i = 0; i < reader.FieldCount; i++)
            {
                Console.Write("{0}\t", reader.GetValue(i));
            }
            Console.WriteLine();
        }
    }

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

        // If you have not included "Asynchronous Processing=true" in the
        // connection string, the command is not able
        // to execute asynchronously.
        return "Data Source=(local);Integrated Security=true;" +
            "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
    }
}
Imports System.Data.SqlClient

Module Module1
    Sub Main()
        ' This example is not terribly useful, but it proves a point.
        ' The WAITFOR statement simply adds enough time to prove the 
        ' asynchronous nature of the command.
        Dim commandText As String = _
         "WAITFOR DELAY '00:00:03';" & _
         "SELECT ProductID, Name FROM Production.Product WHERE ListPrice < 100"

        RunCommandAsynchronously(commandText, GetConnectionString())

        Console.WriteLine("Press ENTER to continue.")
        Console.ReadLine()
    End Sub

    Private Sub RunCommandAsynchronously( _
     ByVal commandText As String, ByVal connectionString As String)

        ' Given command text and connection string, asynchronously execute
        ' the specified command against the connection. For this example,
        ' the code displays an indicator as it is working, verifying the 
        ' asynchronous behavior. 
        Try
            ' The code does not need to handle closing the connection explicitly--
            ' the use of the CommandBehavior.CloseConnection option takes care
            ' of that for you. 
            Dim connection As New SqlConnection(connectionString)
            Dim command As New SqlCommand(commandText, connection)

            connection.Open()
            Dim result As IAsyncResult = _
              command.BeginExecuteReader(CommandBehavior.CloseConnection)

            ' Although it is not necessary, the following code
            ' displays a counter in the console window, indicating that 
            ' the main thread is not blocked while awaiting the command 
            ' results.
            Dim count As Integer = 0
            While Not result.IsCompleted
                count += 1
                Console.WriteLine("Waiting ({0})", count)
                ' Wait for 1/10 second, so the counter
                ' does not consume all available resources 
                ' on the main thread.
                Threading.Thread.Sleep(100)
            End While

            ' The "using" statement closes the SqlDataReader when it is 
            ' done executing.
            Using reader As SqlDataReader = command.EndExecuteReader(result)
                DisplayResults(reader)
            End Using
        Catch ex As SqlException
            Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message)
        Catch ex As InvalidOperationException
            Console.WriteLine("Error: {0}", ex.Message)
        Catch ex As Exception
            ' You might want to pass these errors
            ' back out to the caller.
            Console.WriteLine("Error: {0}", ex.Message)
        End Try
    End Sub

    Private Sub DisplayResults(ByVal reader As SqlDataReader)
        ' Display the data within the reader.
        While reader.Read()
            ' Display all the columns. 
            For i As Integer = 0 To reader.FieldCount - 1
                Console.Write("{0} ", reader.GetValue(i))
            Next
            Console.WriteLine()
        End While
    End Sub

    Private Function GetConnectionString() As String
        ' To avoid storing the connection string in your code,            
        ' you can retrieve it from a configuration file. 

        ' If you have not included "Asynchronous Processing=true" in the
        ' connection string, the command is not able
        ' to execute asynchronously.
        Return "Data Source=(local);Integrated Security=true;" & _
          "Initial Catalog=AdventureWorks; Asynchronous Processing=true"
    End Function
End Module

備註

BeginExecuteReader方法會啟動以非同步方式執行 transact-sql 語句或預存程式以傳回資料列的程式, 以便在執行語句時, 同時執行其他工作。The BeginExecuteReader method starts the process of asynchronously executing a Transact-SQL statement or stored procedure that returns rows, so that other tasks can run concurrently while the statement is executing. 當語句完成時, 開發人員必須呼叫EndExecuteReader方法來完成作業, 並取出命令所傳回的。 SqlDataReaderWhen the statement has completed, developers must call the EndExecuteReader method to finish the operation and retrieve the SqlDataReader returned by the command. 方法會立即傳回, 但在程式碼執行對應EndExecuteReader的方法呼叫之前, 它不能執行任何其他對相同SqlCommand物件啟動同步或非同步執行的呼叫。 BeginExecuteReaderThe BeginExecuteReader method returns immediately, but until the code executes the corresponding EndExecuteReader method call, it must not execute any other calls that start a synchronous or asynchronous execution against the same SqlCommand object. 在命令EndExecuteReader執行完成之前呼叫, SqlCommand會導致物件封鎖, 直到執行完成為止。Calling the EndExecuteReader before the command's execution is completed causes the SqlCommand object to block until the execution is finished.

behavior參數可讓您指定選項, 以控制命令和其連接的行為。The behavior parameter lets you specify options that control the behavior of the command and its connection. 這些值可以結合在一起 (使用程式設計語言的OR運算子); 一般而言, 開發人員會CommandBehavior.CloseConnection使用此值, 確保執行時間在關閉時SqlDataReader關閉連接。These values can be combined together (using the programming language's OR operator); generally, developers use the CommandBehavior.CloseConnection value to make sure that the connection is closed by the runtime when the SqlDataReader is closed.

請注意, 命令文字和參數會以同步方式傳送到伺服器。Note that the command text and parameters are sent to the server synchronously. 如果傳送的是大型命令或多個參數, 這個方法可能會在寫入期間封鎖。If a large command or many parameters are sent, this method may block during writes. 傳送命令之後, 方法會立即傳回, 而不會等候伺服器的回應, 也就是非同步讀取。After the command is sent, the method returns immediately without waiting for an answer from the server--that is, reads are asynchronous. 雖然命令執行是非同步, 但值提取仍然是同步的。Although command execution is asynchronous, value fetching is still synchronous. 這表示如果需要更Read多資料, 而且基礎網路的讀取作業區塊, 則的呼叫可能會封鎖。This means that calls to Read may block if more data is required and the underlying network's read operation blocks.

因為此多載不支援回呼程式, 所以開發人員必須輪詢以判斷命令是否已完成, 使用IsCompleted BeginExecuteNonQuery方法所傳回之的IAsyncResult屬性, 或等候完成使用AsyncWaitHandle 傳回IAsyncResult之的屬性的一或多個命令。Because this overload does not support a callback procedure, developers must either poll to determine whether the command has completed, using the IsCompleted property of the IAsyncResult returned by the BeginExecuteNonQuery method; or wait for the completion of one or more commands using the AsyncWaitHandle property of the returned IAsyncResult.

如果您使用ExecuteReaderBeginExecuteReader來存取 XML 資料, SQL Server 會傳回超過2033個字元的任何 xml 結果, 其長度為每個2033個字元的多個資料列。If you use ExecuteReader or BeginExecuteReader to access XML data, SQL Server returns any XML results greater than 2,033 characters in length in multiple rows of 2,033 characters each. 若要避免此行為, ExecuteXmlReaderBeginExecuteXmlReader使用或來讀取 FOR XML 查詢。To avoid this behavior, use ExecuteXmlReader or BeginExecuteXmlReader to read FOR XML queries.

另請參閱

BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object) BeginExecuteReader(AsyncCallback, Object)

指定回呼程序和狀態資訊時,啟始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並且從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand and retrieves one or more result sets from the server, given a callback procedure and state information.

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

參數

callback
AsyncCallback AsyncCallback AsyncCallback AsyncCallback

完成執行命令時叫用的 AsyncCallback 委派。An AsyncCallback delegate that is invoked when the command's execution has completed. 傳遞 null (在 Microsoft Visual Basic 中為 Nothing) 以表示不需要回呼。Pass null (Nothing in Microsoft Visual Basic) to indicate that no callback is required.

stateObject
Object Object Object Object

已傳遞至回呼程序的使用者定義狀態物件。A user-defined state object that is passed to the callback procedure. 使用 AsyncState 屬性,從回呼程序內擷取這個物件。Retrieve this object from within the callback procedure using the AsyncState property.

傳回

IAsyncResult,可用於輪詢或等待結果 (或兩者);叫用 EndExecuteReader(IAsyncResult) 以傳回一個可用於擷取所傳回資料列的 SqlDataReader 執行個體時,也需要這個值。An IAsyncResult that can be used to poll, wait for results, or both; this value is also needed when invoking EndExecuteReader(IAsyncResult), which returns a SqlDataReader instance which can be used to retrieve the returned rows.

例外狀況

Value 設為 Stream 時,使用 BinaryVarBinary 以外的 SqlDbTypeA SqlDbType other than Binary or VarBinary was used when Value was set to Stream. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

-或--or-

Value 設為 TextReader 時,使用 CharNCharNVarCharVarCharXml 以外的 SqlDbTypeA SqlDbType other than Char, NChar, NVarChar, VarChar, or Xml was used when Value was set to TextReader.

-或--or-

Value 設定為 XmlReader 時,使用 Xml 以外的 SqlDbTypeA SqlDbType other than Xml was used when Value was set to XmlReader.

執行命令文字時發生的任何錯誤。Any error that occurred while executing the command text.

-或--or-

串流作業期間發生逾時。A timeout occurred during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

定義這個 SqlCommand 之連接的連接字串中未包含名稱/值組 "Asynchronous Processing=true"。The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this SqlCommand.

-或--or-

在串流作業期間已關閉或卸除的 SqlConnectionThe SqlConnection closed or dropped during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間發生錯誤。An error occurred in a Stream, XmlReader or TextReader object during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間已關閉。The Stream, XmlReader or TextReader object was closed during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

範例

下列 Windows 應用程式示範 BeginExecuteReader 方法的用法,它會執行包含數秒延遲 (模擬長時間執行命令) 的 Transact-SQL 陳述式。The following Windows application demonstrates the use of the BeginExecuteReader method, executing a Transact-SQL statement that includes a delay of a few seconds (emulating a long-running command). 因為此範例會以非同步方式執行命令, 所以表單會在等候結果時維持回應。Because the sample executes the command asynchronously, the form remains responsive while awaiting the results. 這個範例會傳遞執行SqlCommand中的物件stateObject做為參數; 這麼做可讓您輕鬆SqlCommand地從回呼程式內抓取物件EndExecuteReader , 讓程式碼可以呼叫對應至的方法。BeginExecuteReader的初始呼叫。This example passes the executing SqlCommand object as the stateObject parameter; doing so makes it simple to retrieve the SqlCommand object from within the callback procedure, so that the code can call the EndExecuteReader method corresponding to the initial call to BeginExecuteReader.

這個範例示範許多重要的技巧。This example demonstrates many important techniques. 這包括呼叫方法, 從個別的執行緒與表單互動。This includes calling a method that interacts with the form from a separate thread. 此外, 此範例也會示範如何封鎖使用者同時執行多次命令, 以及如何確保在呼叫回呼程式之前不會關閉表單。In addition, this example demonstrates how you must block users from executing a command multiple times concurrently, and how you must make sure that the form does not close before the callback procedure is called.

若要設定此範例,請建立新的 Windows 應用程式。To set up this example, create a new Windows application. 將控制項、控制項和Label控制項放在表單上 (接受每個控制項的預設名稱)。 DataGridView ButtonPut a Button control, a DataGridView control, and a Label control on the form (accepting the default name for each control). 將下列程式碼新增至表單的類別, 並視您的環境需要修改連接字串。Add the following code to the form's class, modifying the connection string as needed for your environment.

using System.Data.SqlClient;

namespace Microsoft.AdoDotNet.CodeSamples
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Hook up the form's Load event handler (you can double-click on 
        // the form's design surface in Visual Studio), and then add 
        // this code to the form's class:

        // You need this delegate in order to fill the grid from
        // a thread other than the form's thread. See the HandleCallback
        // procedure for more information.
        private delegate void FillGridDelegate(SqlDataReader reader);

        // You need this delegate to update the status bar.
        private delegate void DisplayStatusDelegate(string Text);

        // This flag ensures that the user does not attempt
        // to restart the command or close the form while the 
        // asynchronous command is executing.
        private bool isExecuting = false;

        // Because the overloaded version of BeginExecuteReader
        // demonstrated here does not allow you to have the connection
        // closed automatically, this example maintains the 
        // connection object externally, so that it is available for closing.
        private SqlConnection connection = null;

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

        private void FillGrid(SqlDataReader reader)
        {
            try
            {
                DataTable table = new DataTable();
                table.Load(reader);
                this.dataGridView1.DataSource = table;
                DisplayStatus("Ready");
            }
            catch (Exception ex)
            {
                // Because you are guaranteed this procedure
                // is running from within the form's thread,
                // it can directly interact with members of the form.
                DisplayStatus(string.Format("Ready (last attempt failed: {0})",
                    ex.Message));
            }
            finally
            {
                // Do not forget to close the connection, as well.
                if (reader != null)
                {
                    reader.Close();
                }
                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;
                SqlDataReader reader = command.EndExecuteReader(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. Therefore you cannot simply call code that 
                // fills the grid, like this:
                // FillGrid(reader);
                // 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. 
                FillGridDelegate del = new FillGridDelegate(FillGrid);
                this.Invoke(del, reader);
                // Do not close the reader here, because it is being used in 
                // a separate thread. Instead, have the procedure you have
                // called close the reader once it is done with it.
            }
            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 there is none of 
                // your code 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 DisplayStatusDelegate(DisplayStatus),
                    "Error: " + ex.Message);
            }
            finally
            {
                isExecuting = false;
            }
        }

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

            // If you do not include the Asynchronous Processing=true name/value pair,
            // you wo not be able to execute the command asynchronously.
            return "Data Source=(local);Integrated Security=true;" +
                "Initial Catalog=AdventureWorks; Asynchronous Processing=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
                {
                    DisplayStatus("Connecting...");
                    connection = new SqlConnection(GetConnectionString());
                    // To emulate a long-running query, wait for 
                    // a few seconds before retrieving the real data.
                    command = new SqlCommand("WAITFOR DELAY '0:0:5';" +
                        "SELECT ProductID, Name, ListPrice, Weight FROM Production.Product",
                        connection);
                    connection.Open();

                    DisplayStatus("Executing...");
                    isExecuting = true;
                    // Although it is not required that you pass the 
                    // SqlCommand object as the second parameter in the 
                    // BeginExecuteReader call, doing so makes it easier
                    // to call EndExecuteReader in the callback procedure.
                    AsyncCallback callback = new AsyncCallback(HandleCallback);
                    command.BeginExecuteReader(callback, command);
                }
                catch (Exception ex)
                {
                    DisplayStatus("Error: " + ex.Message);
                    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 FormClosingEventHandler(Form1_FormClosing);
        }

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

Public Class Form1
    ' Add this code to the form's class:
    ' You need this delegate in order to fill the grid from
    ' a thread other than the form's thread. See the HandleCallback
    ' procedure for more information.
    Private Delegate Sub FillGridDelegate(ByVal reader As SqlDataReader)

    ' You need this delegate to update the status bar.
    Private Delegate Sub DisplayStatusDelegate(ByVal Text As String)

    ' This flag ensures that the user does not attempt
    ' to restart the command or close the form while the 
    ' asynchronous command is executing.
    Private isExecuting As Boolean

    ' Because the overloaded version of BeginExecuteReader
    ' demonstrated here does not allow you to have the connection
    ' closed automatically, this example maintains the 
    ' connection object externally, so that it is available for closing.
    Private connection As SqlConnection

    Private Sub DisplayStatus(ByVal Text As String)
        Me.Label1.Text = Text
    End Sub

    Private Sub FillGrid(ByVal reader As SqlDataReader)
        Try
            Dim table As New DataTable
            table.Load(reader)
            Me.DataGridView1.DataSource = table
            DisplayStatus("Ready")

        Catch ex As Exception
            ' Because you are guaranteed this procedure
            ' is running from within the form's thread,
            ' it can directly interact with members of the form.
            DisplayStatus(String.Format("Ready (last attempt failed: {0})", ex.Message))
        Finally
            ' Do not forget to close the connection, as well.
            If Not reader Is Nothing Then
                reader.Close()
            End If
            If Not connection Is Nothing Then
                connection.Close()
            End If
        End Try
    End Sub

    Private Sub HandleCallback(ByVal result As IAsyncResult)
        Try
            ' Retrieve the original command object, passed
            ' to this procedure in the AsyncState property
            ' of the IAsyncResult parameter.
            Dim command As SqlCommand = CType(result.AsyncState, SqlCommand)
            Dim reader As SqlDataReader = command.EndExecuteReader(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. Therefore you cannot simply call code that 
            ' fills the grid, like this:
            ' FillGrid(reader)

            ' 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. 
            Dim del As New FillGridDelegate(AddressOf FillGrid)
            Me.Invoke(del, reader)
            ' Do not close the reader here, because it is being used in 
            ' a separate thread. Instead, have the procedure you have
            ' called close the reader once it is done with it.

        Catch ex As Exception
            ' 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 there is none of 
            ' your code 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:
            Me.Invoke(New DisplayStatusDelegate(AddressOf DisplayStatus), _
             "Error: " & ex.Message)
        Finally
            isExecuting = False
        End Try
    End Sub

    Private Function GetConnectionString() As String
        ' To avoid storing the connection string in your code,
        ' you can retrieve it from a configuration file. 

        ' If you do not include the Asynchronous Processing=true name/value pair,
        ' you wo not be able to execute the command asynchronously.

        Return "Data Source=(local);Integrated Security=true;" & _
        "Initial Catalog=AdventureWorks; Asynchronous Processing=true"
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
        If isExecuting Then
            MessageBox.Show(Me, _
                "Already executing. Please wait until the current query " & _
                "has completed.")
        Else
            Dim command As SqlCommand
            Try
                DisplayStatus("Connecting...")
                connection = New SqlConnection(GetConnectionString())
                ' To emulate a long-running query, wait for 
                ' a few seconds before retrieving the real data.
                command = New SqlCommand( _
                 "WAITFOR DELAY '0:0:5';" & _
                 "SELECT ProductID, Name, ListPrice, Weight FROM Production.Product", _
                 connection)
                connection.Open()

                DisplayStatus("Executing...")
                isExecuting = True
                ' Although it is not required that you pass the 
                ' SqlCommand object as the second parameter in the 
                ' BeginExecuteReader call, doing so makes it easier
                ' to call EndExecuteReader in the callback procedure.
                Dim callback As New AsyncCallback(AddressOf HandleCallback)
                command.BeginExecuteReader(callback, command)

            Catch ex As Exception
                DisplayStatus("Error: " & ex.Message)
                If connection IsNot Nothing Then
                    connection.Close()
                End If
            End Try
        End If
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.FormClosingEventArgs) _
        Handles Me.FormClosing
        If isExecuting Then
            MessageBox.Show(Me, "Cannot close the form until " & _
              "the pending asynchronous command has completed. Please wait...")
            e.Cancel = True
        End If
    End Sub
End Class

備註

BeginExecuteReader方法會啟動以非同步方式執行 transact-sql 語句或預存程式以傳回資料列的程式, 以便在執行語句時, 同時執行其他工作。The BeginExecuteReader method starts the process of asynchronously executing a Transact-SQL statement or stored procedure that returns rows, so that other tasks can run concurrently while the statement is executing. 當語句完成時, 開發人員必須呼叫EndExecuteReader方法來完成作業, 並取出命令所傳回的。 SqlDataReaderWhen the statement has completed, developers must call the EndExecuteReader method to finish the operation and retrieve the SqlDataReader returned by the command. 方法會立即傳回, 但在程式碼執行對應EndExecuteReader的方法呼叫之前, 它不能執行任何其他對相同SqlCommand物件啟動同步或非同步執行的呼叫。 BeginExecuteReaderThe BeginExecuteReader method returns immediately, but until the code executes the corresponding EndExecuteReader method call, it must not execute any other calls that start a synchronous or asynchronous execution against the same SqlCommand object. 在命令EndExecuteReader執行之前呼叫, SqlCommand會導致物件封鎖, 直到執行完成為止。Calling the EndExecuteReader before the command's execution is completed cause the SqlCommand object to block until the execution is finished.

參數可讓您AsyncCallback指定當語句完成時所呼叫的委派。 callbackThe callback parameter lets you specify an AsyncCallback delegate that is called when the statement has completed. 您可以從這個EndExecuteReader委派程式內, 或從應用程式內的任何其他位置呼叫方法。You can call the EndExecuteReader method from within this delegate procedure, or from any other location within your application. 此外, 您可以在stateObject參數中傳遞任何物件, 而回呼程式可以AsyncState使用屬性來抓取這項資訊。In addition, you can pass any object in the stateObject parameter, and your callback procedure can retrieve this information using the AsyncState property.

請注意, 命令文字和參數會以同步方式傳送到伺服器。Note that the command text and parameters are sent to the server synchronously. 如果傳送的是大型命令或多個參數, 這個方法可能會在寫入期間封鎖。If a large command or many parameters are sent, this method may block during writes. 傳送命令之後, 方法會立即傳回, 而不會等候伺服器的回應, 也就是非同步讀取。After the command is sent, the method returns immediately without waiting for an answer from the server--that is, reads are asynchronous. 雖然命令執行是非同步, 但值提取仍然是同步的。Although command execution is asynchronous, value fetching is still synchronous. 這表示如果需要更Read多資料, 而且基礎網路的讀取作業區塊, 則的呼叫可能會封鎖。This means that calls to Read may block if more data is required and the underlying network's read operation blocks.

由於回呼程式是從 Microsoft .NET 執行時間所提供的背景執行緒內執行, 因此您必須採取嚴謹的方法來處理應用程式內的跨執行緒互動。Because the callback procedure executes from within a background thread supplied by the Microsoft .NET runtime, it is very important that you take a rigorous approach to handling cross-thread interactions from within your applications. 例如, 您不能從回呼程式內與表單的內容互動;如果您需要更新表單, 您必須切換回表單的執行緒, 才能執行工作。For example, you must not interact with a form's contents from within your callback procedure; should you have to update the form, you must switch back to the form's thread in order to do your work. 本主題中的範例將示範此行為。The example in this topic demonstrates this behavior.

在作業執行期間發生的所有錯誤都會在回呼程式中擲回為例外狀況。All errors that occur during the execution of the operation are thrown as exceptions in the callback procedure. 您必須處理回呼程式中的例外狀況, 而不是在主應用程式中。You must handle the exception in the callback procedure, not in the main application. 如需在回呼程式中處理例外狀況的詳細資訊, 請參閱本主題中的範例。See the example in this topic for additional information on handling exceptions in the callback procedure.

如果您使用ExecuteReaderBeginExecuteReader來存取 XML 資料, SQL Server 會傳回超過2033個字元的任何 xml 結果, 其長度為每個2033個字元的多個資料列。If you use ExecuteReader or BeginExecuteReader to access XML data, SQL Server returns any XML results greater than 2,033 characters in length in multiple rows of 2,033 characters each. 若要避免此行為, ExecuteXmlReaderBeginExecuteXmlReader使用或來讀取 FOR XML 查詢。To avoid this behavior, use ExecuteXmlReader or BeginExecuteXmlReader to read FOR XML queries.

另請參閱

BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior) BeginExecuteReader(AsyncCallback, Object, CommandBehavior)

指定回呼程序和狀態資訊時,使用其中一個 CommandBehavior 值,起始這個 SqlCommand 所描述之 Transact-SQL 陳述式或預存程序的非同步執行,並從伺服器擷取一或多個結果集。Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this SqlCommand, using one of the CommandBehavior values, and retrieving one or more result sets from the server, given a callback procedure and state information.

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

參數

callback
AsyncCallback AsyncCallback AsyncCallback AsyncCallback

完成執行命令時叫用的 AsyncCallback 委派。An AsyncCallback delegate that is invoked when the command's execution has completed. 傳遞 null (在 Microsoft Visual Basic 中為 Nothing) 以表示不需要回呼。Pass null (Nothing in Microsoft Visual Basic) to indicate that no callback is required.

stateObject
Object Object Object Object

已傳遞至回呼程序的使用者定義狀態物件。A user-defined state object that is passed to the callback procedure. 使用 AsyncState 屬性,從回呼程序內擷取這個物件。Retrieve this object from within the callback procedure using the AsyncState property.

behavior
CommandBehavior CommandBehavior CommandBehavior CommandBehavior

其中一個 CommandBehavior 值,表示陳述式執行和資料擷取的選項。One of the CommandBehavior values, indicating options for statement execution and data retrieval.

傳回

IAsyncResult,可用於輪詢或等待結果 (或兩者);叫用 EndExecuteReader(IAsyncResult) 以傳回一個可用於擷取所傳回資料列的 SqlDataReader 執行個體時,也需要這個值。An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndExecuteReader(IAsyncResult), which returns a SqlDataReader instance which can be used to retrieve the returned rows.

例外狀況

Value 設為 Stream 時,使用 BinaryVarBinary 以外的 SqlDbTypeA SqlDbType other than Binary or VarBinary was used when Value was set to Stream. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

-或--or-

Value 設為 TextReader 時,使用 CharNCharNVarCharVarCharXml 以外的 SqlDbTypeA SqlDbType other than Char, NChar, NVarChar, VarChar, or Xml was used when Value was set to TextReader.

-或--or-

Value 設定為 XmlReader 時,使用 Xml 以外的 SqlDbTypeA SqlDbType other than Xml was used when Value was set to XmlReader.

執行命令文字時發生的任何錯誤。Any error that occurred while executing the command text.

-或--or-

串流作業期間發生逾時。A timeout occurred during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

定義這個 SqlCommand 之連接的連接字串中未包含名稱/值組 "Asynchronous Processing=true"。The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this SqlCommand.

-或--or-

在串流作業期間已關閉或卸除的 SqlConnectionThe SqlConnection closed or dropped during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間發生錯誤。An error occurred in a Stream, XmlReader or TextReader object during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

StreamXmlReaderTextReader 物件在串流作業期間已關閉。The Stream, XmlReader or TextReader object was closed during a streaming operation. 如需串流的詳細資訊,請參閱 SqlClient 串流支援For more information about streaming, see SqlClient Streaming Support.

範例

下列 Windows 應用程式示範 BeginExecuteReader 方法的用法,它會執行包含數秒延遲 (模擬長時間執行命令) 的 Transact-SQL 陳述式。The following Windows application demonstrates the use of the BeginExecuteReader method, executing a Transact-SQL statement that includes a delay of a few seconds (emulating a long-running command). 因為此範例會以非同步方式執行命令, 所以表單會在等候結果時維持回應。Because the sample executes the command asynchronously, the form remains responsive while awaiting the results. 這個範例會傳遞執行SqlCommand中的物件stateObject做為參數; 這麼做可讓您輕鬆SqlCommand地從回呼程式內抓取物件EndExecuteReader , 讓程式碼可以呼叫對應至的方法。BeginExecuteReader的初始呼叫。This example passes the executing SqlCommand object as the stateObject parameter; doing so makes it simple to retrieve the SqlCommand object from within the callback procedure, so that the code can call the EndExecuteReader method corresponding to the initial call to BeginExecuteReader.

這個範例示範許多重要的技巧。This example demonstrates many important techniques. 這包括呼叫方法, 從個別的執行緒與表單互動。This includes calling a method that interacts with the form from a separate thread. 此外, 此範例也會示範如何封鎖使用者同時執行多次命令, 以及如何確保在呼叫回呼程式之前不會關閉表單。In addition, this example demonstrates how you must block users from executing a command multiple times concurrently, and how you must make sure that the form does not close before the callback procedure is called.

若要設定此範例,請建立新的 Windows 應用程式。To set up this example, create a new Windows application. 將控制項、控制項和Label控制項放在表單上 (接受每個控制項的預設名稱)。 DataGridView ButtonPut a Button control, a DataGridView control, and a Label control on the form (accepting the default name for each control). 將下列程式碼新增至表單的類別, 並視您的環境需要修改連接字串。Add the following code to the form's class, modifying the connection string as needed for your environment.

這個範例會behaviorCommandBehavior.CloseConnection參數中傳遞值, 使傳回SqlDataReader的在關閉時自動關閉其連接。This example passes the CommandBehavior.CloseConnection value in the behavior parameter, causing the returned SqlDataReader to automatically close its connection when it is closed.

using System.Data.SqlClient;

namespace Microsoft.AdoDotNet.CodeSamples
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        // Hook up the form's Load event handler (you can double-click on 
        // the form's design surface in Visual Studio), and then add 
        // this code to the form's class:
        // You need this delegate in order to fill the grid from
        // a thread other than the form's thread. See the HandleCallback
        // procedure for more information.
        private delegate void FillGridDelegate(SqlDataReader reader);

        // You need this delegate to update the status bar.
        private delegate void DisplayStatusDelegate(string Text);

        // This flag ensures that the user does not attempt
        // to restart the command or close the form while the 
        // asynchronous command is executing.
        private bool isExecuting;

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

        private void FillGrid(SqlDataReader reader)
        {
            try
            {
                DataTable table = new DataTable();
                table.Load(reader);
                this.dataGridView1.DataSource = table;
                DisplayStatus("Ready");
            }
            catch (Exception ex)
            {
                // Because you are guaranteed this procedure
                // is running from within the form's thread,
                // it can directly interact with members of the form.
                DisplayStatus(string.Format("Ready (last attempt failed: {0})",
                    ex.Message));
            }
            finally
            {
                // Closing the reader also closes the connection,
                // because this reader was created using the 
                // CommandBehavior.CloseConnection value.
                if (reader != null)
                {
                    reader.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;
                SqlDataReader reader = command.EndExecuteReader(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. Therefore you cannot simply call code that 
                // fills the grid, like this:
                // FillGrid(reader);
                // 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. 
                FillGridDelegate del = new FillGridDelegate(FillGrid);
                this.Invoke(del, reader);
                // Do not close the reader here, because it is being used in 
                // a separate thread. Instead, have the procedure you have
                // called close the reader once it is done with it.
            }
            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 there is none of 
                // your code 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 DisplayStatusDelegate(DisplayStatus), "Error: " +
                    ex.Message);
            }
            finally
            {
                isExecuting = false;
            }
        }

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

            // If you do not include the Asynchronous Processing=true name/value pair,
            // you wo not be able to execute the command asynchronously.
            return "Data Source=(local);Integrated Security=true;" +
                "Initial Catalog=AdventureWorks; Asynchronous Processing=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;
                SqlConnection connection = null;
                try
                {
                    DisplayStatus("Connecting...");
                    connection = new SqlConnection(GetConnectionString());
                    // To emulate a long-running query, wait for 
                    // a few seconds before retrieving the real data.
                    command = new SqlCommand("WAITFOR DELAY '0:0:5';" +
                        "SELECT ProductID, Name, ListPrice, Weight FROM Production.Product",
                        connection);
                    connection.Open();

                    DisplayStatus("Executing...");
                    isExecuting = true;
                    // Although it is not required that you pass the 
                    // SqlCommand object as the second parameter in the 
                    // BeginExecuteReader call, doing so makes it easier
                    // to call EndExecuteReader in the callback procedure.
                    AsyncCallback callback = new AsyncCallback(HandleCallback);
                    command.BeginExecuteReader(callback, command,
                        CommandBehavior.CloseConnection);
                }
                catch (Exception ex)
                {
                    DisplayStatus("Error: " + ex.Message);
                    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 FormClosingEventHandler(Form1_FormClosing);
        }

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

Public Class Form1
    ' Add this code to the form's class:
    ' You this delegate in order to fill the grid from
    ' a thread other than the form's thread. See the HandleCallback
    ' procedure for more information.
    Private Delegate Sub FillGridDelegate(ByVal reader As SqlDataReader)

    ' You need this delegate to update the status bar.
    Private Delegate Sub DisplayStatusDelegate(ByVal Text As String)

    ' This flag ensures that the user does not attempt
    ' to restart the command or close the form while the 
    ' asynchronous command is executing.
    Private isExecuting As Boolean

    Private Sub DisplayStatus(ByVal Text As String)
        Me.Label1.Text = Text
    End Sub

    Private Sub FillGrid(ByVal reader As SqlDataReader)
        Try
            Dim table As New DataTable
            table.Load(reader)
            Me.DataGridView1.DataSource = table
            DisplayStatus("Ready")

        Catch ex As Exception
            ' Because you are guaranteed this procedure
            ' is running from within the form's thread,
            ' it can directly interact with members of the form.
            DisplayStatus(String.Format("Ready (last attempt failed: {0})", ex.Message))
        Finally
            ' Closing the reader also closes the connection,
            ' because this reader was created using the 
            ' CommandBehavior.CloseConnection value.
            If reader IsNot Nothing Then
                reader.Close()
            End If
        End Try
    End Sub

    Private Sub HandleCallback(ByVal result As IAsyncResult)
        Try
            ' Retrieve the original command object, passed
            ' to this procedure in the AsyncState property
            ' of the IAsyncResult parameter.
            Dim command As SqlCommand = CType(result.AsyncState, SqlCommand)
            Dim reader As SqlDataReader = command.EndExecuteReader(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. Therefore you cannot simply call code that 
            ' fills the grid, like this:
            ' FillGrid(reader)

            ' 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. 
            Dim del As New FillGridDelegate(AddressOf FillGrid)
            Me.Invoke(del, reader)

            ' Do not close the reader here, because it is being used in 
            ' a separate thread. Instead, have the procedure you have
            ' called close the reader once it is done with it.

        Catch ex As Exception
            ' 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 there is none of 
            ' your code 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:
            Me.Invoke(New DisplayStatusDelegate(AddressOf DisplayStatus), _
             "Error: " & ex.Message)
        Finally
            isExecuting = False
        End Try
    End Sub

    Private Function GetConnectionString() As String
        ' To avoid storing the connection string in your code,
        ' you can retrieve it from a configuration file. 

        ' If you do not include the Asynchronous Processing=true name/value pair,
        ' you wo not be able to execute the command asynchronously.

        Return "Data Source=(local);Integrated Security=true;" & _
        "Initial Catalog=AdventureWorks; Asynchronous Processing=true"
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
        If isExecuting Then
            MessageBox.Show(Me, "Already executing. Please wait until the current query " & _
             "has completed.")
        Else
            Dim connection As SqlConnection
            Dim command As SqlCommand
            Try
                DisplayStatus("Connecting...")
                connection = New SqlConnection(GetConnectionString())
                ' To emulate a long-running query, wait for 
                ' a few seconds before retrieving the real data.
                command = New SqlCommand( _
                 "WAITFOR DELAY '0:0:5';" & _
                 "SELECT ProductID, Name, ListPrice, Weight FROM Production.Product", _
                 connection)
                connection.Open()

                DisplayStatus("Executing...")
                isExecuting = True
                ' Although it is not required that you pass the 
                ' SqlCommand object as the second parameter in the 
                ' BeginExecuteReader call, doing so makes it easier
                ' to call EndExecuteReader in the callback procedure.
                Dim callback As New AsyncCallback(AddressOf HandleCallback)
                command.BeginExecuteReader(callback, command, _
                  CommandBehavior.CloseConnection)

            Catch ex As Exception
                DisplayStatus("Error: " & ex.Message)
                If connection IsNot Nothing Then
                    connection.Close()
                End If
            End Try
        End If
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If isExecuting Then
            MessageBox.Show(Me, "Cannot close the form until " & _
             "the pending asynchronous command has completed. Please wait...")
            e.Cancel = True
        End If
    End Sub
End Class

備註

BeginExecuteReader方法會啟動以非同步方式執行 transact-sql 語句或預存程式以傳回資料列的程式, 以便在執行語句時, 同時執行其他工作。The BeginExecuteReader method starts the process of asynchronously executing a Transact-SQL statement or stored procedure that returns rows, so that other tasks can run concurrently while the statement is executing. 當語句完成時, 開發人員必須呼叫EndExecuteReader方法來完成作業, 並取出命令所傳回的。 SqlDataReaderWhen the statement has completed, developers must call the EndExecuteReader method to finish the operation and retrieve the SqlDataReader returned by the command. 方法會立即傳回, 但在程式碼執行對應EndExecuteReader的方法呼叫之前, 它不能執行任何其他對相同SqlCommand物件啟動同步或非同步執行的呼叫。 BeginExecuteReaderThe BeginExecuteReader method returns immediately, but until the code executes the corresponding EndExecuteReader method call, it must not execute any other calls that start a synchronous or asynchronous execution against the same SqlCommand object. 在命令EndExecuteReader執行完成之前呼叫, SqlCommand會導致物件封鎖, 直到執行完成為止。Calling the EndExecuteReader before the command's execution is completed causes the SqlCommand object to block until the execution is finished.

參數可讓您AsyncCallback指定當語句完成時所呼叫的委派。 callbackThe callback parameter lets you specify an AsyncCallback delegate that is called when the statement has completed. 您可以從這個EndExecuteReader委派程式內, 或從應用程式內的任何其他位置呼叫方法。You can call the EndExecuteReader method from within this delegate procedure, or from any other location within your application. 此外, 您可以在stateObject參數中傳遞任何物件, 而回呼程式可以AsyncState使用屬性來抓取這項資訊。In addition, you can pass any object in the stateObject parameter, and your callback procedure can retrieve this information using the AsyncState property.

behavior參數可讓您指定選項, 以控制命令和其連接的行為。The behavior parameter lets you specify options that control the behavior of the command and its connection. 這些值可以結合在一起 (使用程式設計語言的Or運算子); 一般而言, 開發人員會CloseConnection使用此值, 確保執行時間在關閉時SqlDataReader關閉連接。These values can be combined together (using the programming language's Or operator); generally, developers use the CloseConnection value to make sure that the connection is closed by the runtime when the SqlDataReader is closed. 開發人員也可以在事先知道 transact-sql SqlDataReader語句或預SingleRow存程式只會傳回單一資料列時, 藉由指定值來優化的行為。Developers can also optimize the behavior of the SqlDataReader by specifying the SingleRow value when it is known in advance that the Transact-SQL statement or stored procedure only returns a single row.

請注意, 命令文字和參數會以同步方式傳送到伺服器。Note that the command text and parameters are sent to the server synchronously. 如果傳送的是大型命令或多個參數, 這個方法可能會在寫入期間封鎖。If a large command or many parameters are sent, this method may block during writes. 傳送命令之後, 方法會立即傳回, 而不會等候伺服器的回應, 也就是非同步讀取。After the command is sent, the method returns immediately without waiting for an answer from the server--that is, reads are asynchronous. 雖然命令執行是非同步, 但值提取仍然是同步的。Although command execution is asynchronous, value fetching is still synchronous. 這表示如果需要更Read多資料, 而且基礎網路的讀取作業區塊, 則的呼叫可能會封鎖。This means that calls to Read may block if more data is required and the underlying network's read operation blocks.

由於回呼程式是從 Microsoft .NET common language runtime 所提供的背景執行緒內執行, 因此您必須採取嚴謹的方法來處理應用程式內的跨執行緒互動。Because the callback procedure executes from within a background thread supplied by the Microsoft .NET common language runtime, it is very important that you take a rigorous approach to handling cross-thread interactions from within your applications. 例如, 您不能從回呼程式內與表單的內容互動--如果您必須更新表單, 您必須切換回表單的執行緒, 才能執行您的工作。For example, you must not interact with a form's contents from within your callback procedure--should you have to update the form, you must switch back to the form's thread in order to do your work. 本主題中的範例將示範此行為。The example in this topic demonstrates this behavior.

在作業執行期間發生的所有錯誤都會在回呼程式中擲回為例外狀況。All errors that occur during the execution of the operation are thrown as exceptions in the callback procedure. 您必須處理回呼程式中的例外狀況, 而不是在主應用程式中。You must handle the exception in the callback procedure, not in the main application. 如需在回呼程式中處理例外狀況的詳細資訊, 請參閱本主題中的範例。See the example in this topic for additional information on handling exceptions in the callback procedure.

如果您使用ExecuteReaderBeginExecuteReader來存取 XML 資料, SQL Server 會傳回超過2033個字元的任何 xml 結果, 其長度為每個2033個字元的多個資料列。If you use ExecuteReader or BeginExecuteReader to access XML data, SQL Server will return any XML results greater than 2,033 characters in length in multiple rows of 2,033 characters each. 若要避免此行為, ExecuteXmlReaderBeginExecuteXmlReader使用或來讀取 FOR XML 查詢。To avoid this behavior, use ExecuteXmlReader or BeginExecuteXmlReader to read FOR XML queries.

另請參閱

適用於