Sorunum gerçek bir proje sorununa dayanıyor, ancak System.Threading.Tasks
kitaplığını hiç kullanmadım ya da iş parçacıkları içeren herhangi bir ciddi programlama gerçekleştirmeme rağmen sorusu özel kitaplık hakkında bilgi eksik olabilir. ve uyumsuzluğun gerçekten programlama anlamında ne anlama geldiğine dair daha genel bir yanlış anlaşılma.Gerçekten eşzamansız iki SQL sorgusu nasıl yapılır
Benim gerçek dünya durumum bu - Bir kullanıcı hakkında veri almam gerekiyor. Benim şu anki senaryomda finansal veri var, yani Accounts
, tüm Deposits
ve tüm kullanıcı için Consignations
'a ihtiyacım var. Benim durumumda bu, her bir özellik için kayıtların milyonu sorgulamak anlamına gelir ve her sorgu nispeten yavaştır, ancak Accounts
'un getirilmesi, Deposits
'un getirilmesinden birkaç kez daha yavaştır. Bu yüzden kullanmak için gidiyorum üç banka ürünleri için üç sınıf tanımladık ve belirli kullanıcının tüm banka ürünlerinin Verileri getirilecek istediğimde böyle bir şey yapmak:
List<Account> accounts = GetAccountsForClient(int clientId);
List<Deposit> deposits = GetDepositsForClient(int clientId);
List<Consignation> consignations = GetConsignationsForClient(int clientId);
Yani sorun başlar Burada tüm bu üç listeyi aynı anda almam gerekiyor, çünkü onları tüm kullanıcı verilerini görüntülediğim görünüme ileteceğim. böylece üç ürün için veri toplamak için toplam süreyi (Ben doğru burada terimini kullanıyorum varsa) şimdi olduğu yürütme senkron olduğu gibi Fakat geçerli:
Total_Time = Time_To_Get_Accounts + Time_To_Get_Deposits + Time_To_Get_Consignations
Bu iyi değil her sorgu çünkü nispeten yavaş olduğu için toplam süre oldukça büyüktür, fakat aynı zamanda accounts
sorgusu diğer iki sorgudan çok daha fazla zaman alır, böylece bugün kafamın içine girme fikri - "Bu sorguları eşzamanlı olarak çalıştırabilirsem" idi. Belki de bu konuyla ilgili en büyük yanlış anlama geliyor ama benim için bu fikre en yakın olanı asenkronize etmektir, bu yüzden belki de Total_Time
en yavaş sorgunun zamanı olmayacak, ancak üç sorgunun toplamından çok daha hızlı olacaktır.
Kodum karmaşık olduğundan, oldukça iyi yapmaya çalıştığım şeyi yansıttığımı düşündüğüm basit bir kullanım durumu oluşturdum.
public static async Task<int> GetAccounts()
{
int total1 = 0;
using (SqlConnection connection = new SqlConnection(connString))
{
string query1 = "SELECT COUNT(*) FROM [MyDb].[dbo].[Accounts]";
SqlCommand command = new SqlCommand(query1, connection);
connection.Open();
for (int i = 0; i < 19000000; i++)
{
string s = i.ToString();
}
total1 = (int) await command.ExecuteScalarAsync();
Console.WriteLine(total1.ToString());
}
return total1;
}
ve ikinci yöntem: Ben iki yöntemi var böyle diyoruz
public static async Task<int> GetDeposits()
{
int total2 = 0;
using (SqlConnection connection = new SqlConnection(connString))
{
string query2 = "SELECT COUNT(*) FROM [MyDb].[dbo].[Deposits]";
SqlCommand command = new SqlCommand(query2, connection);
connection.Open();
total2 = (int) await command.ExecuteScalarAsync();
Console.WriteLine(total2.ToString());
}
return total2;
}
:
static void Main(string[] args)
{
Console.WriteLine(GetAccounts().Result.ToString());
Console.WriteLine(GetDeposits().Result.ToString());
}
Eğer ben ilk GetAccounts()
arayıp yürütme yavaş görebileceğiniz gibi Amaca göre, bir sonraki yönteme devam etme şansı veriyorum. Ancak belli bir süre için sonuç alamıyorum ve daha sonra konsolda aynı anda basılmış olsun.
Yani sorun - nasıl bir sonraki yönteme gitmek için, ilk yöntemin bitmesini beklemeyecek şekilde. Genel olarak kod yapısı o kadar önemli değil, anlamaya çalıştığım şey, aynı anda yürütmek için her iki soruyu da yapmanın bir yolu varsa. Buradaki örnek, belki de istenilen sonucu alabileceğim noktaya kadar genişletilebilen araştırmamın sonucudur.
P.S Sadece kullanıyorum bir yöntemle başladım çünkü ExecuteScalarAsync();
kullanıyorum. Gerçekte Scalar
ve Reader
kullanacağım.
. Orijinal fikrim, sonucu farklı bir zamanda elde etmekti. Açıklamanızdan belki de bunun gibi belki de toplam zaman en yavaş süreye eşittir, ancak ikinci yönteme eklediğimde (int i = 0; i <19000000; i ++) { string s = i.ToString(); } 'zaman iki katına çıktı. Bu garip. Eğer simultane bir şekilde yapıldıysa ve bu durumda sorguların milisaniye sürdüğü için, yöntemlerden sadece birinin yavaşlamasıyla aynı zamanı beklemekteydim. – Leron
Kendimi netleştirdiğime emin değilim. Benim fikrim şu ki, 'GetAccounts()' 3 saniye ve 'GetDeposits()' saniyeden az alırsa sonuç almak için 3 saniye bekliyorum. Ama eğer 'GetDeposits()' i 3sn yerine tekrar 3 sn yerine çalıştırmaya zorlarsam, çünkü bu en yavaş zaman ve görev aynı zamanda 6 saniye sonra sonuca ulaşır. Bu yaklaşımı olduğu gibi uygularsam ne olur ne olur. Bir şey mi eksik? – Leron
@Leron asenkron, paralel olarak aynı değildir. Yöntemleriniz eşzamansız bir parçaya ve senkronize bir parçaya (I/O ve CPU) sahiptir. Eşzamansız bölümleri eşzamanlı olarak yürütürken, cevaplarımda olduğu gibi kolayca yapabilirsiniz. Senkronize parçayı paralel olarak yürütmek için, 2 iş parçacığı 'Task.Run' ile kullanmanız gerekir. İstediğin bu mu? – i3arnon