Zaman uyumsuz sorgu ve kaydetme
Dekont
Yalnızca EF6'ya Doğru - Bu sayfada ele alınan özellikler, API'ler vb. Entity Framework 6'da sunulmuştur. Önceki bir sürümü kullanıyorsanız, bilgilerin bir kısmı veya tümü geçerli değildir.
EF6, .NET 4.5'te kullanıma sunulan zaman uyumsuz sorgu ve bekleme anahtar sözcüklerini kullanarak zaman uyumsuz sorgu ve kaydetme desteği sunar. Tüm uygulamalar zaman uyumsuzluktan yararlanamayabilir ancak uzun süre çalışan, ağ veya G/Ç'ye bağlı görevleri işlerken istemci yanıt hızını ve sunucu ölçeklenebilirliğini geliştirmek için kullanılabilir.
Zaman uyumsuz gerçekten ne zaman kullanılır?
Bu kılavuzun amacı, zaman uyumsuz ve zaman uyumlu program yürütme arasındaki farkı gözlemlemesini kolaylaştıracak şekilde zaman uyumsuz kavramları tanıtmaktır. Bu izlenecek yol, zaman uyumsuz programlamanın avantaj sağladığı temel senaryoların hiçbirini göstermek için tasarlanmamıştır.
Zaman uyumsuz programlama öncelikle yönetilen bir iş parçacığından işlem süresi gerektirmeyen bir işlemi beklerken diğer işleri yapmak için geçerli yönetilen iş parçacığını (.NET kodu çalıştıran iş parçacığı) boşaltmaya odaklanır. Örneğin, veritabanı altyapısı bir sorguyu işlerken .NET kodu tarafından yapılacak bir şey yoktur.
İstemci uygulamalarında (WinForms, WPF vb.) zaman uyumsuz işlem gerçekleştirilirken kullanıcı arabiriminin yanıt vermesini sağlamak için geçerli iş parçacığı kullanılabilir. Sunucu uygulamalarında (ASP.NET vb.) iş parçacığı diğer gelen istekleri işlemek için kullanılabilir- bu, bellek kullanımını azaltabilir ve/veya sunucunun aktarım hızını artırabilir.
Zaman uyumsuz kullanan uygulamaların çoğunda fark edilebilir bir avantajı olmaz ve hatta zarar verebilir. İşlemeden önce belirli bir senaryonuzda zaman uyumsuzun etkisini ölçmek için testleri, profil oluşturmayı ve sağduyuyu kullanın.
Zaman uyumsuz hakkında daha fazla bilgi edinmek için aşağıda daha fazla kaynak bulabilirsiniz:
- Brandon Bray'in .NET 4.5'te async/await'a genel bakış
- MSDN Kitaplığı'ndaki Zaman Uyumsuz Programlama sayfaları
Modeli oluşturma
Modelimizi oluşturmak ve veritabanını oluşturmak için İlk Kod iş akışını kullanacağız ancak zaman uyumsuz işlevsellik, EF Tasarım Aracı ile oluşturulanlar da dahil olmak üzere tüm EF modelleriyle çalışır.
- Konsol Uygulaması oluşturma ve AsyncDemo olarak çağırma
- EntityFramework NuGet paketini ekleme
- Çözüm Gezgini'da AsyncDemo projesine sağ tıklayın
- NuGet Paketlerini Yönet... öğesini seçin .
- NuGet Paketlerini Yönet iletişim kutusunda Çevrimiçi sekmesini seçin ve EntityFramework paketini seçin
- Yükle'ye tıklayın
- Aşağıdaki uygulamayla bir Model.cs sınıfı ekleyin
using System.Collections.Generic;
using System.Data.Entity;
namespace AsyncDemo
{
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
}
Zaman uyumlu program oluşturma
Artık bir EF modelimiz olduğuna göre, veri erişimi gerçekleştirmek için bu modeli kullanan bazı kodlar yazalım.
- Program.cs dosyasının içeriğini aşağıdaki kodla değiştirin
using System;
using System.Linq;
namespace AsyncDemo
{
class Program
{
static void Main(string[] args)
{
PerformDatabaseOperations();
Console.WriteLine("Quote of the day");
Console.WriteLine(" Don't worry about the world coming to an end today... ");
Console.WriteLine(" It's already tomorrow in Australia.");
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
public static void PerformDatabaseOperations()
{
using (var db = new BloggingContext())
{
// Create a new blog and save it
db.Blogs.Add(new Blog
{
Name = "Test Blog #" + (db.Blogs.Count() + 1)
});
Console.WriteLine("Calling SaveChanges.");
db.SaveChanges();
Console.WriteLine("SaveChanges completed.");
// Query for all blogs ordered by name
Console.WriteLine("Executing query.");
var blogs = (from b in db.Blogs
orderby b.Name
select b).ToList();
// Write all blogs out to Console
Console.WriteLine("Query completed with following results:");
foreach (var blog in blogs)
{
Console.WriteLine(" " + blog.Name);
}
}
}
}
}
Bu kod, veritabanına yeni bir Blog kaydeden yöntemini çağırır PerformDatabaseOperations
ve ardından veritabanından tüm Blogları alır ve konsola yazdırır. Bundan sonra, program konsola günün bir alıntısını yazar.
Kod zaman uyumlu olduğundan, programı çalıştırırken aşağıdaki yürütme akışını gözlemleyebiliriz:
SaveChanges
yeni Blogu veritabanına göndermeye başlarSaveChanges
Tamamlayan- Tüm Bloglar için sorgu veritabanına gönderilir
- Sorgu döndürür ve sonuçlar Konsol'a yazılır
- Günün alıntısı Konsol'a yazılır
Zaman uyumsuz hale getirme
Artık programımızı çalıştırdığımıza göre, yeni zaman uyumsuz ve await anahtar sözcüklerini kullanmaya başlayabiliriz. Program.cs dosyasında aşağıdaki değişiklikleri yaptık
- 2. Satır: Ad alanının using deyimi
System.Data.Entity
, EF zaman uyumsuz uzantı yöntemlerine erişmemizi sağlar. - 4. Satır: Ad alanının using deyimi
System.Threading.Tasks
, türünü kullanmamızaTask
olanak tanır. - Satır 12 & 18: Programın ilerleme durumunu
PerformSomeDatabaseOperations
izleyen (12. satır) ve ardından program için tüm çalışmalar tamamlandıktan sonra bu görevin program yürütmesini engelleyen bir görev olarak yakalıyoruz (18. satır). - 25. Satır: olarak işaretlenecek ve döndürülecek şekilde
async
Task
güncelleştirdikPerformSomeDatabaseOperations
. - 35. Satır: Şimdi zaman uyumsuz sürümünü
SaveChanges
çağırıyoruz ve tamamlanmasını bekliyoruz. - 42. Satır: Şimdi Async sürümünü
ToList
çağırıyoruz ve sonucu bekliyoruz.
Ad alanında System.Data.Entity
kullanılabilir uzantı yöntemlerinin kapsamlı bir listesi için sınıfına QueryableExtensions
bakın. Ayrıca using deyimlerinize de eklemeniz using System.Data.Entity
gerekir.
using System;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
namespace AsyncDemo
{
class Program
{
static void Main(string[] args)
{
var task = PerformDatabaseOperations();
Console.WriteLine("Quote of the day");
Console.WriteLine(" Don't worry about the world coming to an end today... ");
Console.WriteLine(" It's already tomorrow in Australia.");
task.Wait();
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
public static async Task PerformDatabaseOperations()
{
using (var db = new BloggingContext())
{
// Create a new blog and save it
db.Blogs.Add(new Blog
{
Name = "Test Blog #" + (db.Blogs.Count() + 1)
});
Console.WriteLine("Calling SaveChanges.");
await db.SaveChangesAsync();
Console.WriteLine("SaveChanges completed.");
// Query for all blogs ordered by name
Console.WriteLine("Executing query.");
var blogs = await (from b in db.Blogs
orderby b.Name
select b).ToListAsync();
// Write all blogs out to Console
Console.WriteLine("Query completed with following results:");
foreach (var blog in blogs)
{
Console.WriteLine(" - " + blog.Name);
}
}
}
}
}
Kod artık zaman uyumsuz olduğuna göre, programı çalıştırdığımızda farklı bir yürütme akışı gözlemleyebiliriz:
SaveChanges
yeni Blogu veritabanına göndermeye başlar
Komut veritabanına gönderildikten sonra geçerli yönetilen iş parçacığında işlem süresi gerekmez.PerformDatabaseOperations
yöntemi döndürür (yürütmeyi tamamlamamış olsa da) ve Main yöntemindeki program akışı devam eder.- Günün alıntısı Konsol'a yazılır
Main yönteminde yapılacak başka iş olmadığından, veritabanı işlemi tamamlanana kadar yönetilen iş parçacığı çağrıdaWait
engellenir. İşlem tamamlandıktan sonra geri kalanımızPerformDatabaseOperations
yürütülecek. SaveChanges
Tamamlayan- Tüm Bloglar için sorgu veritabanına gönderilir
Sorgu veritabanında işlenirken yönetilen iş parçacığının başka işler yapması da serbesttir. Diğer tüm yürütmeler tamamlandığından, iş parçacığı Bekleme çağrısında durur. - Sorgu döndürür ve sonuçlar Konsol'a yazılır
Paket servis
ARTıK EF'in zaman uyumsuz yöntemlerini kullanmanın ne kadar kolay olduğunu gördük. Basit bir konsol uygulamasında zaman uyumsuzluk avantajları çok belirgin olmasa da, uzun süre çalışan veya ağa bağlı etkinliklerin uygulamayı engelleyebileceği veya bellek ayak izini artırmak için çok sayıda iş parçacığına neden olabileceği durumlarda da bu stratejiler uygulanabilir.