Uzak bir sunucuda işlem yapmanız gereken her zaman, program isteğinizi oluşturur, gönderir, sonra yanıt bekler. Örnek olarak SaveChanges()
ve SaveChangesAsync()
kullanacağım, ancak aynı Find()
ve FindAsync()
için geçerlidir.
Veritabanınıza eklemeniz gereken 100 + öğeden oluşan bir listenin myList
olduğunu varsayalım. veritabanına değişiklikleri devam etmek SaveChanges()
çağrı sonra, masanın MyTable
listeyi myList
ekleyin MyEDM
ait
using(var context = new MyEDM())
{
context.MyTable.AddRange(myList);
context.SaveChanges();
}
Öncelikle oluşturmak ve örnek: O eklemek için, fonksiyon şöyle görünecektir. İstediğiniz gibi çalışır, kayıtlar işe alınır, ancak programınız taahhüt tamamlanana kadar başka bir şey yapamaz. Bu, ne yaptığınıza bağlı olarak uzun zaman alabilir. Kayıtlarda değişiklik yapmakla yükümlü olursanız, tarafın bunları bir seferde yerine getirmesi gerekir (Bir kez bir kez kaydetme güncellemeleri için 2 dakika sürdüm)!
Bu sorunu çözmek için iki şeyden birini yapabilirsiniz. İlk olarak, eki işlemek için yeni bir iş parçacığı başlatabilirsiniz. Bu, yürütmeye devam etmek için çağrı iş parçacığını serbest bırakacak olsa da, yalnızca orada oturup bekleyeceğiniz yeni bir iş parçacığı oluşturdunuz. Bu yüke gerek yok ve bu async await
modelinin çözdüğü şey.
I/O karşıtları için, await
hızlı bir şekilde en iyi arkadaşınız olur.
using(var context = new MyEDM())
{
Console.WriteLine("Save Starting");
context.MyTable.AddRange(myList);
await context.SaveChangesAsync();
Console.WriteLine("Save Complete");
}
Çok küçük bir değişiklik, ancak kod verimliliği ve performansı üzerinde derin etkileri vardır: Yukarıdaki kod bölümünü alarak, biz olmak değiştirebilir. Peki ne olur? kodun başlangıcı Eğer MyEDM
bir örneğini oluşturmak ve sizin myList
MyTable
eklemek aynıdır. Ancak, await context.SaveChangesAsync()
'u aradığınızda, kodunun yürütülmesi çağıran işleve geri döner! Bu kayıtların tamamlanmasını beklerken, kodunuz çalışmaya devam edebilir. Eğer böyle bir işlevi olurdu Neden
public async Task MyCallingFunction()
{
Console.WriteLine("Function Starting");
Task saveTask = SaveRecords(GenerateNewRecords());
for(int i = 0; i < 1000; i++){
Console.WriteLine("Continuing to execute!");
}
await saveTask;
Console.Log("Function Complete");
}
, bilmiyorum, ama bu gösterileri nasıl verir neyi: Yukarıdaki kod public async Task SaveRecords(List<MyTable> saveList)
imzasını vardı içeriyordu işlevini Say, çağıran işlevi aşağıdaki gibi görünebilir async await
çalışır. Önce olanları gözden geçirelim.
Yürütme işlemi MyCallingFunction
, Function Starting
girer ve Save Starting
konsoluna yazılır, daha sonra SaveChangesAsync()
işlevi çağrılır. Bu noktada, yürütme MyCallingFunction
'a döner ve 'Dönmeye Devam Ediyor' for döngüsü için 1000 defaya kadar girer. SaveChangesAsync()
finiş olduğunda, yürütmeişlevine geri döner ve Save Complete
konsoluna yazılır. SaveRecords
tamamlanıncaya her şeyi sonra, yürütme hakkı SaveChangesAsync()
bittiğinde öyleydi idi MyCallingFunction
devam edecektir. Şaşkın?
Function Starting
Save Starting
Continuing to execute!
Continuing to execute!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Save Complete!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Function Complete!
Ya da belki: İşte bir örnek çıkışı
async await
güzelliği, kodunuz bitirmek için bir şey beklerken çalışmaya devam edebilir olduğunu
Function Starting
Save Starting
Continuing to execute!
Continuing to execute!
Save Complete!
Continuing to execute!
Continuing to execute!
Continuing to execute!
....
Continuing to execute!
Function Complete!
. Gerçekte, kendi çağıran fonksiyonu olarak bir işlev daha böyle olurdu:
public async Task MyCallingFunction()
{
List<Task> myTasks = new List<Task>();
myTasks.Add(SaveRecords(GenerateNewRecords()));
myTasks.Add(SaveRecords2(GenerateNewRecords2()));
myTasks.Add(SaveRecords3(GenerateNewRecords3()));
myTasks.Add(SaveRecords4(GenerateNewRecords4()));
await Task.WhenAll(myTasks.ToArray());
}
Burada, aynı zamanda de gidiş dört farklı kaydetmek rekor fonksiyonlara sahiptir. async await
kullanarak MyCallingFunction
çok daha hızlı tamamlayacak, daha sonra bireysel SaveRecords
fonksiyonları seri olarak çağrıldı.
Henüz üzerinde dokunmadım bir şey await
anahtar kelimedir. Bu, mevcut fonksiyonun tamamlanmasını bekleyen Task
ne kadar devam etmesini engeller. SaveRecords
fonksiyonu bitene kadar orijinal MyCallingFunction
durumunda Yani, hat Function Complete
konsola yazılır edilmeyecektir. Eğer async await
kullanmak için bir seçenek varsa
Uzun lafın kısası, bunu büyük ölçüde uygulama performansını artıracaktır gerektiği gibi.
zaman uyumsuz fazla, * çok * istemci uygulamalarında engellemesini istemci UI iş parçacığı durdurma daha fazla. Eminim yakında gelen bir uzman cevabı var. – jdphenix