Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu örnekleri kullanmak için Microsoft.Data.SqlClient NuGet paketini yükleyin. Microsoft.Data.SqlClient, zaman uyumsuz bir bağlantı dizesi seçeneği olmadan burada gösterilen EndExecute ve BeginExecute yöntemlerini destekler. eklemeyinAsynchronous Processing=true; Microsoft. Data.SqlClient bu anahtar sözcüğü desteklemez. Yeni kodda, await ile ExecuteReaderAsync ve ExecuteNonQueryAsync tercih edin; işlemleri bir istek iş parçacığını engellemeden koordine etmek için Task.WhenAny veya Task.WhenAll kullanın.
Zaman uyumsuz işlemleri işlemeye yönelik geri çağırma ve yoklama modelleri, uygulamanız aynı anda yalnızca bir zaman uyumsuz işlemi işlerken kullanışlıdır. Bekleme modelleri, birden çok zaman uyumsuz işlemi işlemenin daha esnek bir yolunu sağlar. Bunları uygulamak için kullanılan yöntemler için WaitHandle adlı iki Bekleme modeli vardır: Wait (Any) modeli ve Wait (Tümü) modeli.
İki Wait modelinden birini kullanmak için, AsyncWaitHandle, BeginExecuteXmlReader veya BeginExecuteReader yöntemleri tarafından döndürülen BeginExecuteNonQuery nesnesinin IAsyncResult özelliğini kullanın. WaitHandle veya WaitAny öğesine WaitAll nesnelerinden oluşan bir dizi geçirin.
Her iki Wait yöntemi de zaman uyumsuz işlemleri izleyerek tamamlanmasını bekler. WaitAny yöntemi tüm işlemlerin tamamlanmasını veya zaman aşımına uğradımasını bekler. Belirli bir işlemin tamamlanmasını bildiğinizde, bu işlemin sonuçlarını işleyebilir ve sonraki işlemin tamamlanmasını veya zaman aşımına uğradıktan sonra beklemeye devam edebilirsiniz. yöntemi, WaitAll devam etmeden önce örnek dizisindeki tüm işlemlerin WaitHandle tamamlanmasını veya zaman aşımına uğramasını bekler.
Wait modellerinin avantajı, farklı sunucularda bir miktar uzunlukta birden çok işlem çalıştırmanız gerektiğinde veya sunucunuz tüm sorguları aynı anda işlemek için yeterince güçlü olduğunda dikkat çekicidir. Burada sunulan örneklerde, üç sorgu, önemsiz WAITFOR sorgulara farklı uzunluklarda SELECT komutlar ekleyerek uzun işlemleri taklit eder.
Örnek: Bekleme (Herhangi Bir) Model
Aşağıdaki örnekte Wait (Any) modeli gösterilmektedir. Üç zaman uyumsuz işlem başlatıldıktan sonra kod, herhangi bir işlemin tamamlanmasını beklemek için WaitAny çağrılır. Tamamlanan her işlem için kod EndExecuteReader çağırır ve sonuçta elde edilen SqlDataReader değerini okur. Bir uygulama, sayfanın bir bölümünü doldurmak için bu sonuçları kullanabilir. Bunun yerine örnek, ilgili metin kutusuna tamamlanma süresini ekler. Kod tamamlanmış bir işlemi işlediğinde her seferinde bunu kaydeder.
Tamamlanan tutamaçlar sinyalli kaldığından, örnek tamamlanan her işlemi yeniden beklemeden önce bekleyen listelerden kaldırır.
Bu örneği ayarlamak için yeni bir ASP.NET Web Sitesi projesi oluşturun. Sayfaya bir Button denetim ve dört TextBox denetim yerleştirin (her denetim için varsayılan adı kabul eder).
Formun sınıfına aşağıdaki kodu ekleyin. Her iki Bekleme modeli örneğinde, GetConnectionString tarafından döndürülen üç noktayı bağlantı dizesi ile değiştirin. Windows tümleşik kimlik doğrulamasına sahip uzak bir sunucu için Server=<server>;Database=<database>;Integrated Security=true;Encrypt=true kullanın.
<database> ve <server> değerlerini sunucu ve veritabanı adlarınızla değiştirin ve istemcinin güvendiği bir sunucu sertifikası yapılandırın. Diğer kimlik doğrulama seçenekleri için bkz. Bağlantı dizesi söz dizimi.
' Add these to the top of the class
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports Microsoft.Data.SqlClient
Imports System.Threading
' Add this code to the page's class:
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "..."
End Function
Sub Button1_Click( _
ByVal sender As Object, ByVal e As System.EventArgs)
' In a real-world application, you might be connecting to
' three different servers or databases. For the example,
' we connect to only one.
Dim connection1 As New SqlConnection(GetConnectionString())
Dim connection2 As New SqlConnection(GetConnectionString())
Dim connection3 As New SqlConnection(GetConnectionString())
' To keep the example simple, all three asynchronous
' processes select a row from the same table. WAITFOR
' commands are used to emulate long-running processes
' that complete after different periods of time.
Dim commandText1 As String = _
"WAITFOR DELAY '0:0:01';" & _
"SELECT * FROM Production.Product " & _
"WHERE ProductNumber = 'BL-2036'"
Dim commandText2 As String = _
"WAITFOR DELAY '0:0:05';" & _
"SELECT * FROM Production.Product " & _
"WHERE ProductNumber = 'BL-2036'"
Dim commandText3 As String = _
"WAITFOR DELAY '0:0:10';" & _
"SELECT * FROM Production.Product " & _
"WHERE ProductNumber = 'BL-2036'"
Dim waitHandles As New List(Of WaitHandle)
Dim pending As New List(Of Integer) From {0, 1, 2}
Try
' For each process, open a connection and begin execution.
' Use the IAsyncResult object returned by
' BeginExecuteReader to add a WaitHandle for the process
' to the pending list.
connection1.Open()
Dim command1 As New SqlCommand(commandText1, connection1)
Dim result1 As IAsyncResult = _
command1.BeginExecuteReader()
waitHandles.Add(result1.AsyncWaitHandle)
connection2.Open()
Dim command2 As New SqlCommand(commandText2, connection2)
Dim result2 As IAsyncResult = _
command2.BeginExecuteReader()
waitHandles.Add(result2.AsyncWaitHandle)
connection3.Open()
Dim command3 As New SqlCommand(commandText3, connection3)
Dim result3 As IAsyncResult = _
command3.BeginExecuteReader()
waitHandles.Add(result3.AsyncWaitHandle)
Dim index As Integer
For countWaits As Integer = 1 To 3
' WaitAny waits for any of the processes to complete.
' The return value is either the index of the
' array element whose process just completed, or
' the WaitTimeout value.
index = WaitHandle.WaitAny(waitHandles.ToArray(), 60000, False)
If index = WaitHandle.WaitTimeout Then
Throw New Exception("Timeout")
End If
' This example doesn't actually do anything with the
' data returned by the processes, but the code opens
' readers for each just to demonstrate the concept.
' Instead of using the returned data to fill the
' controls on the page, the example adds the time
' the process was completed to the corresponding
' text box.
Select Case pending(index)
Case 0
Dim reader1 As SqlDataReader
reader1 = command1.EndExecuteReader(result1)
If reader1.Read Then
TextBox1.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
End If
reader1.Close()
Case 1
Dim reader2 As SqlDataReader
reader2 = command2.EndExecuteReader(result2)
If reader2.Read Then
TextBox2.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
End If
reader2.Close()
Case 2
Dim reader3 As SqlDataReader
reader3 = command3.EndExecuteReader(result3)
If reader3.Read Then
TextBox3.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
End If
reader3.Close()
End Select
waitHandles.RemoveAt(index)
pending.RemoveAt(index)
Next
Catch ex As Exception
TextBox4.Text = ex.ToString
End Try
connection1.Close()
connection2.Close()
connection3.Close()
End Sub
// Add the following using directives, if they aren't already there.
using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using Microsoft.Data.SqlClient;
// Add this code to the page's class
string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
{
return "...";
}
void Button1_Click(object sender, System.EventArgs e)
{
// In a real-world application, you might be connecting to
// three different servers or databases. For the example,
// we connect to only one.
SqlConnection connection1 =
new SqlConnection(GetConnectionString());
SqlConnection connection2 =
new SqlConnection(GetConnectionString());
SqlConnection connection3 =
new SqlConnection(GetConnectionString());
// To keep the example simple, all three asynchronous
// processes select a row from the same table. WAITFOR
// commands are used to emulate long-running processes
// that complete after different periods of time.
string commandText1 = "WAITFOR DELAY '0:0:01';" +
"SELECT * FROM Production.Product " +
"WHERE ProductNumber = 'BL-2036'";
string commandText2 = "WAITFOR DELAY '0:0:05';" +
"SELECT * FROM Production.Product " +
"WHERE ProductNumber = 'BL-2036'";
string commandText3 = "WAITFOR DELAY '0:0:10';" +
"SELECT * FROM Production.Product " +
"WHERE ProductNumber = 'BL-2036'";
try
// For each process, open a connection and begin
// execution. Use the IAsyncResult object returned by
// BeginExecuteReader to add a WaitHandle for the
// process to the pending list.
{
connection1.Open();
SqlCommand command1 =
new SqlCommand(commandText1, connection1);
IAsyncResult result1 = command1.BeginExecuteReader();
WaitHandle waitHandle1 = result1.AsyncWaitHandle;
connection2.Open();
SqlCommand command2 =
new SqlCommand(commandText2, connection2);
IAsyncResult result2 = command2.BeginExecuteReader();
WaitHandle waitHandle2 = result2.AsyncWaitHandle;
connection3.Open();
SqlCommand command3 =
new SqlCommand(commandText3, connection3);
IAsyncResult result3 = command3.BeginExecuteReader();
WaitHandle waitHandle3 = result3.AsyncWaitHandle;
List<WaitHandle> waitHandles = new List<WaitHandle> {
waitHandle1, waitHandle2, waitHandle3
};
List<int> pending = new List<int> { 0, 1, 2 };
int index;
for (int countWaits = 0; countWaits <= 2; countWaits++)
{
// WaitAny waits for any of the processes to
// complete. The return value is either the index
// of the array element whose process just
// completed, or the WaitTimeout value.
index = WaitHandle.WaitAny(waitHandles.ToArray(),
60000, false);
if (index == WaitHandle.WaitTimeout)
{
throw new Exception("Timeout");
}
// This example doesn't actually do anything with
// the data returned by the processes, but the
// code opens readers for each just to demonstrate
// the concept.
// Instead of using the returned data to fill the
// controls on the page, the example adds the time
// the process was completed to the corresponding
// text box.
switch (pending[index])
{
case 0:
SqlDataReader reader1;
reader1 =
command1.EndExecuteReader(result1);
if (reader1.Read())
{
TextBox1.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader1.Close();
break;
case 1:
SqlDataReader reader2;
reader2 =
command2.EndExecuteReader(result2);
if (reader2.Read())
{
TextBox2.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader2.Close();
break;
case 2:
SqlDataReader reader3;
reader3 =
command3.EndExecuteReader(result3);
if (reader3.Read())
{
TextBox3.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader3.Close();
break;
}
waitHandles.RemoveAt(index);
pending.RemoveAt(index);
}
}
catch (Exception ex)
{
TextBox4.Text = ex.ToString();
}
connection1.Close();
connection2.Close();
connection3.Close();
}
Örnek: Wait (Tümü) Modeli
Aşağıdaki örnek, Wait (All) modelini göstermektedir. Üç zaman uyumsuz işlem başlatıldıktan sonra, işlemlerin tamamlanmasını veya zaman aşımına uğramasını beklemek için WaitAll yöntem çağrılır.
Wait (Any) modeli örneğinde olduğu gibi, işlemin tamamlanma zamanı işleme karşılık gelen bir metin kutusuna eklenir. Metin kutularındaki zamanlar da noktayı gösterir: Yöntemi izleyen WaitAny kod yalnızca tüm işlemler tamamlandıktan sonra yürütülür.
Bu örneği ayarlamak için yeni bir ASP.NET Web Sitesi projesi oluşturun. Sayfaya bir Button denetim ve dört TextBox denetim yerleştirin (her denetim için varsayılan adı kabul eder).
Ortamınız için gerekli bağlantı dizesi değiştirerek formun sınıfına aşağıdaki kodu ekleyin.
' Add these to the top of the class
Imports System
Imports System.Data
Imports Microsoft.Data.SqlClient
Imports System.Threading
' Add this code to the page's class:
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "..."
End Function
Sub Button1_Click( _
ByVal sender As Object, ByVal e As System.EventArgs)
' In a real-world application, you might be connecting to
' three different servers or databases. For the example,
' we connect to only one.
Dim connection1 As New SqlConnection(GetConnectionString())
Dim connection2 As New SqlConnection(GetConnectionString())
Dim connection3 As New SqlConnection(GetConnectionString())
' To keep the example simple, all three asynchronous
' processes select a row from the same table. WAITFOR
' commands are used to emulate long-running processes
' that complete after different periods of time.
Dim commandText1 As String = _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint + 1 " & _
"WHERE ReorderPoint Is Not Null;" & _
"WAITFOR DELAY '0:0:01';" & _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint - 1 " & _
"WHERE ReorderPoint Is Not Null"
Dim commandText2 As String = _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint + 1 " & _
"WHERE ReorderPoint Is Not Null;" & _
"WAITFOR DELAY '0:0:05';" & _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint - 1 " & _
"WHERE ReorderPoint Is Not Null"
Dim commandText3 As String = _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint + 1 " & _
"WHERE ReorderPoint Is Not Null;" & _
"WAITFOR DELAY '0:0:10';" & _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint - 1 " & _
"WHERE ReorderPoint Is Not Null"
Dim waitHandles(2) As WaitHandle
Try
' For each process, open a connection and begin execution.
' Use the IAsyncResult object returned by
' BeginExecuteReader to add a WaitHandle for the process
' to the array.
connection1.Open()
Dim command1 As New SqlCommand(commandText1, connection1)
Dim result1 As IAsyncResult = _
command1.BeginExecuteNonQuery()
waitHandles(0) = result1.AsyncWaitHandle
connection2.Open()
Dim command2 As New SqlCommand(commandText2, connection2)
Dim result2 As IAsyncResult = _
command2.BeginExecuteNonQuery()
waitHandles(1) = result2.AsyncWaitHandle
connection3.Open()
Dim command3 As New SqlCommand(commandText3, connection3)
Dim result3 As IAsyncResult = _
command3.BeginExecuteNonQuery()
waitHandles(2) = result3.AsyncWaitHandle
' WaitAll waits for all of the processes to complete.
' The return value is True if all processes completed,
' False if any process timed out.
Dim result As Boolean = _
WaitHandle.WaitAll(waitHandles, 60000, False)
If result Then
Dim rowCount1 As Long = _
command1.EndExecuteNonQuery(result1)
TextBox1.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
Dim rowCount2 As Long = _
command2.EndExecuteNonQuery(result2)
TextBox2.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
Dim rowCount3 As Long = _
command3.EndExecuteNonQuery(result3)
TextBox3.Text = _
"Completed " & _
System.DateTime.Now.ToLongTimeString()
Else
Throw New Exception("Timeout")
End If
Catch ex As Exception
TextBox4.Text = ex.ToString
End Try
connection1.Close()
connection2.Close()
connection3.Close()
End Sub
// Add the following using directives, if they aren't already there.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using Microsoft.Data.SqlClient;
// Add this code to the page's class
string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
{
return "...";
}
void Button1_Click(object sender, System.EventArgs e)
{
// In a real-world application, you might be connecting to
// three different servers or databases. For the example,
// we connect to only one.
SqlConnection connection1 =
new SqlConnection(GetConnectionString());
SqlConnection connection2 =
new SqlConnection(GetConnectionString());
SqlConnection connection3 =
new SqlConnection(GetConnectionString());
// To keep the example simple, all three asynchronous
// processes execute UPDATE queries that result in
// no change to the data. WAITFOR
// commands are used to emulate long-running processes
// that complete after different periods of time.
string commandText1 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:01';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
string commandText2 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:05';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
string commandText3 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:10';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
try
// For each process, open a connection and begin
// execution. Use the IAsyncResult object returned by
// BeginExecuteReader to add a WaitHandle for the
// process to the array.
{
connection1.Open();
SqlCommand command1 =
new SqlCommand(commandText1, connection1);
IAsyncResult result1 = command1.BeginExecuteNonQuery();
WaitHandle waitHandle1 = result1.AsyncWaitHandle;
connection2.Open();
SqlCommand command2 =
new SqlCommand(commandText2, connection2);
IAsyncResult result2 = command2.BeginExecuteNonQuery();
WaitHandle waitHandle2 = result2.AsyncWaitHandle;
connection3.Open();
SqlCommand command3 =
new SqlCommand(commandText3, connection3);
IAsyncResult result3 = command3.BeginExecuteNonQuery();
WaitHandle waitHandle3 = result3.AsyncWaitHandle;
WaitHandle[] waitHandles = {
waitHandle1, waitHandle2, waitHandle3
};
bool result;
// WaitAll waits for all of the processes to
// complete. The return value is True if the processes
// all completed successfully, False if any process
// timed out.
result = WaitHandle.WaitAll(waitHandles, 60000, false);
if(result)
{
long rowCount1 =
command1.EndExecuteNonQuery(result1);
TextBox1.Text = "Completed " +
System.DateTime.Now.ToLongTimeString();
long rowCount2 =
command2.EndExecuteNonQuery(result2);
TextBox2.Text = "Completed " +
System.DateTime.Now.ToLongTimeString();
long rowCount3 =
command3.EndExecuteNonQuery(result3);
TextBox3.Text = "Completed " +
System.DateTime.Now.ToLongTimeString();
}
else
{
throw new Exception("Timeout");
}
}
catch (Exception ex)
{
TextBox4.Text = ex.ToString();
}
connection1.Close();
connection2.Close();
connection3.Close();
}