다음을 통해 공유


콘솔 응용 프로그램의 폴링(ADO.NET)

업데이트: November 2007

ADO.NET에서 비동기 작업을 수행하면 다른 스레드에서 다른 작업을 수행하는 동안 한 스레드에서 시간이 많이 걸리는 데이터베이스 작업을 시작할 수 있습니다. 그러나 대부분은 결국 데이터베이스 작업을 완료할 때까지 응용 프로그램을 계속 실행할 수 없는 지점에 이르게 됩니다. 이 경우 비동기 작업을 폴링하여 작업의 완료 여부를 확인하면 도움이 됩니다.

IsCompleted 속성을 사용하면 작업의 완료 여부를 확인할 수 있습니다.

예제

다음 콘솔 응용 프로그램에서는 AdventureWorks 샘플 데이터베이스에서 데이터를 비동기적으로 업데이트합니다. 이 예제에서는 장기 실행 프로세스를 에뮬레이션하기 위해 명령 텍스트에 WAITFOR 문을 삽입합니다. 일반적으로는 명령을 느린 속도로 실행하지 않겠지만 이 경우 그렇게 하면 보다 손쉽게 비동기 작업을 확인할 수 있습니다.

[Visual Basic]

Imports System
Imports System.Data.SqlClient

Module Module1

    Sub Main()
        ' The WAITFOR statement simply adds enough time to prove the 
        ' asynchronous nature of the command.
        Dim commandText As String = _
         "UPDATE Production.Product " & _
         "SET ReorderPoint = ReorderPoint + 1 " & _
         "WHERE ReorderPoint Is Not Null;" & _
         "WAITFOR DELAY '0:0:3';" & _
         "UPDATE Production.Product " & _
         "SET ReorderPoint = ReorderPoint - 1 " & _
         "WHERE ReorderPoint Is Not Null"

        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's working, 
        ' verifying the asynchronous behavior. 
        Using connection As New SqlConnection(connectionString)
            Try
                Dim count As Integer = 0
                Dim command As New SqlCommand(commandText, connection)
                connection.Open()
                Dim result As IAsyncResult = _
                 command.BeginExecuteNonQuery()
                While Not result.IsCompleted
                    Console.WriteLine("Waiting ({0})", count)
                    ' Wait for 1/10 second, so the counter
                    ' doesn't consume all available resources 
                    ' on the main thread.
                    Threading.Thread.Sleep(100)
                    count += 1
                End While
                Console.WriteLine( _
                 "Command complete. Affected {0} rows.", _
                 command.EndExecuteNonQuery(result))
            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 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 will not be able
        ' to execute asynchronously.
        Return "Data Source=(local);Integrated Security=SSPI;" & _
          "Initial Catalog=AdventureWorks; " & _
          "Asynchronous Processing=true"
    End Function
End Module 

[C#]

using System;
using System.Data;
using System.Data.SqlClient;

class Class1
{
    [STAThread]
    static void Main()
    {
        // The WAITFOR statement simply adds enough time to 
        // prove the asynchronous nature of the command.

        string commandText =
          "UPDATE Production.Product SET ReorderPoint = " +
          "ReorderPoint + 1 " +
          "WHERE ReorderPoint Is Not Null;" +
          "WAITFOR DELAY '0:0:3';" +
          "UPDATE Production.Product SET ReorderPoint = " +
          "ReorderPoint - 1 " +
          "WHERE ReorderPoint Is Not Null";

        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's 
        // working, verifying the asynchronous behavior. 
        using (SqlConnection connection =
          new SqlConnection(connectionString))
        {
            try
            {
                int count = 0;
                SqlCommand command = 
                    new SqlCommand(commandText, connection);
                connection.Open();

                IAsyncResult result = 
                    command.BeginExecuteNonQuery();
                while (!result.IsCompleted)
                {
                    Console.WriteLine(
                                    "Waiting ({0})", count++);
                    // Wait for 1/10 second, so the counter
                    // doesn't consume all available 
                    // resources on the main thread.
                    System.Threading.Thread.Sleep(100);
                }
                Console.WriteLine(
                    "Command complete. Affected {0} rows.",
                command.EndExecuteNonQuery(result));
            }
            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 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 will not be able
        // to execute asynchronously.
        return "Data Source=(local);Integrated Security=SSPI;" +
        "Initial Catalog=AdventureWorks; " + 
        "Asynchronous Processing=true";
    }
}

참고 항목

기타 리소스

비동기 작업(ADO.NET)