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.
Zaman uyumsuz programlama kullanarak performans sorunlarını önleyebilir ve uygulamanızın genel yanıt hızını artırabilirsiniz. Ancak, zaman uyumsuz uygulamalar yazmak için geleneksel teknikler karmaşık olabilir, bu da yazmalarını, hata ayıklamalarını ve bakımlarını zorlaştırabilir.
C#, .NET çalışma zamanı içinde zaman uyumsuz desteği kullanan zaman uyumsuz programlama ve basitleştirilmiş yaklaşımı destekler. Derleyici, geliştiricinin eskiden yaptığı zor işi üstlenir ve uygulamanız eşzamanlı koda benzeyen mantıksal bir yapıyı korur. Sonuç olarak, zaman uyumsuz programlamanın tüm avantajlarını çok az çabayla elde edersiniz.
Bu makalede, zaman uyumsuz programlamanın ne zaman ve nasıl kullanılacağına genel bir bakış sağlanır ve ayrıntılar ve örnekler içeren diğer makalelerin bağlantıları yer alır.
Asenkron yanıt hızını artırır
Asenkroni, web erişimi gibi potansiyel olarak engelleyici olan etkinlikler için gereklidir. Bir web kaynağına erişim bazen yavaş veya gecikmeli olabilir. Böyle bir etkinlik zaman uyumlu bir işlemde engellenirse, uygulamanın tamamının beklemesi gerekir. Zaman uyumsuz bir işlemde uygulama, engelleyici olabilecek görev bitene kadar web kaynağına bağımlı olmayan diğer çalışmalarla devam edebilir.
Aşağıdaki tabloda, zaman uyumsuz programlamanın yanıt hızını geliştirdiği tipik alanlar gösterilmektedir. .NET ve Windows Çalışma Zamanı'ndan listelenen API'ler zaman uyumsuz programlamayı destekleyen yöntemler içerir.
| Uygulama alanı | Asenkron yöntemlere sahip .NET türleri | Asenkron yöntemlere sahip Windows Çalışma Zamanı türleri |
|---|---|---|
| Web erişimi | HttpClient | Windows.Web.Http.HttpClient SyndicationClient |
| Dosyalarla çalışma | JsonSerializer StreamReader StreamWriter XmlReader XmlWriter |
StorageFile |
| Görüntülerle çalışma | MediaCapture BitmapEncoder BitmapDecoder |
|
| WCF programlama | Zaman Uyumlu ve Zaman Uyumsuz İşlemler |
Kullanıcı arabirimiyle ilgili tüm etkinlikler genellikle tek bir iş parçacığını paylaştığından, asenkron çalışma, özellikle kullanıcı arabirimi iş parçacığına erişen uygulamalar için büyük bir değer taşır. Zaman uyumlu bir uygulamada herhangi bir işlem engellenirse, tümü engellenir. Uygulamanız yanıt vermeyi durdurur, siz de başarısız olduğunu düşünebilirsiniz, ancak aslında sadece bekliyor.
Zaman uyumsuz yöntemler kullandığınızda, uygulama kullanıcı arabirimine yanıt vermeye devam eder. Örneğin bir pencereyi yeniden boyutlandırabilir veya simge durumuna küçültebilir ya da bitmesini beklemek istemiyorsanız uygulamayı kapatabilirsiniz.
Asenkron tabanlı yaklaşım, asenkron işlemler tasarlarken seçim yapabileceğiniz seçenekler listesine otomatik vites eşdeğerini ekler. Yani, geleneksel zaman uyumsuz programlamanın tüm avantajlarını elde edersiniz, ancak geliştiricinin çok daha az çabasıyla.
Asenkron yöntemleri yazmak kolaydır
C# dilindeki async ve await anahtar sözcükleri, zaman uyumsuz programlamanın kalbidir. Bu iki anahtar sözcüğü kullanarak, .NET Framework, .NET Core veya Windows Çalışma Zamanı'ndaki kaynakları, zaman uyumsuz bir yöntem oluşturmak için, neredeyse zaman uyumlu bir yöntem oluşturmak kadar kolay kullanabilirsiniz.
async anahtar sözcüğünü kullanarak tanımladığınız zaman uyumsuz yöntemler, metotları olarak anılır.
Aşağıdaki örnekte asenkron bir yöntem gösterilmektedir. Koddaki neredeyse her şey size tanıdık görünmelidir.
public async Task<int> GetUrlContentLengthAsync()
{
using var client = new HttpClient();
Task<string> getStringTask =
client.GetStringAsync("https://learn.microsoft.com/dotnet");
DoIndependentWork();
string contents = await getStringTask;
return contents.Length;
}
void DoIndependentWork()
{
Console.WriteLine("Working...");
}
Önceki örnekten çeşitli yöntemler öğrenebilirsiniz. Yöntem imzası ile başlayın.
async değiştiricisini içerir. Dönüş türü Task<int> (daha fazla seçenek için "Dönüş Türleri" bölümüne bakın). Yöntem adı Asyncile biter. bu yöntemin gövdesinde GetStringAsync bir Task<string>döndürür. Bu, görevi await yaptığınızda string (contents) alacağınız anlamına gelir. Görevi beklemeden önce, stringGetStringAsync bağlı olmayan işler yapabilirsiniz.
await işlecine çok dikkat edin.
GetUrlContentLengthAsync'ı askıya alır.
-
GetUrlContentLengthAsynctamamlanana kadargetStringTaskdevam edemez. - Bu sırada, denetim tekrar
GetUrlContentLengthAsync'ı çağırana döner. -
getStringTasktamamlandığında denetim burada devam eder. -
awaitişleci daha sonrastringsonucunugetStringTask'den alır.
return deyimi bir tamsayı sonucu belirtir.
GetUrlContentLengthAsync geçerli olan tüm yöntemler uzunluk değerini almayı bekliyor.
GetUrlContentLengthAsync, GetStringAsync çağırma ve tamamlanmasını bekleme arasında gerçekleştirebileceği bir çalışma yoksa, kodunuzu aşağıdaki tek deyimde çağırıp bekleyerek basitleştirebilirsiniz.
string contents = await client.GetStringAsync("https://learn.microsoft.com/dotnet");
Aşağıdaki özellikler, önceki örneği zaman uyumsuz bir yöntem yapan özellikleri özetler:
Yöntem imzası bir
asyncdeğiştirici içerir.Asenkron bir yöntemin adı, geleneksel olarak "Async" soneki ile biter.
Dönüş türü, aşağıdaki türlerden biridir:
-
Task<TResult> eğer yönteminizde işlenenin türü
TResultolan bir dönüş deyimi varsa. - Yönteminizin return deyimi yoksa veya işleneni olmayan bir return deyimi varsa Task.
-
voidzaman uyumsuz bir olay işleyicisi yazıyorsanız. -
GetAwaiteryöntemi olan başka bir tür.
Daha fazla bilgi için Dönüş türleri ve parametreleri bölümüne bakın.
-
Task<TResult> eğer yönteminizde işlenenin türü
Yöntem genellikle en az bir
awaitifadesi içerir. Bu ifade, beklenen zaman uyumsuz işlem tamamlanana kadar yöntemin devam edemediği bir noktayı işaretler. Bu arada, yöntem askıya alınır ve denetim yöntemin çağıranına geri döner. Bu makalenin sonraki bölümünde, askıya alma noktasında neler olduğu gösterilmektedir.
Zaman uyumsuz yöntemlerde, ne yapmak istediğinizi belirtmek için sağlanan anahtar sözcükleri ve türleri kullanırsınız ve denetim askıya alınmış bir yöntemde bir bekleme noktasına döndüğünde ne olması gerektiğini izlemek de dahil olmak üzere gerisini derleyici yapar. Döngüler ve özel durum işleme gibi bazı rutin işlemlerin geleneksel zaman uyumsuz kodda işlenmesi zor olabilir. Zaman uyumsuz bir yöntem içinde, bu öğeleri zaman uyumlu bir çözümde yazacağınız şekilde yazarsınız ve sorun çözülür.
.NET Framework'ün önceki sürümlerindeki eşzamanlı olmayan işlemler hakkında daha fazla bilgi için TPL ve geleneksel .NET Framework eşzamanlı olmayan programlamabölümüne bakın.
Asenkron bir yöntemde ne olur?
Zaman uyumsuz programlamada anlaşılması gereken en önemli şey, denetim akışının yöntemden yönteme nasıl geçtiğidir. Aşağıdaki diyagram sizi süreç boyunca yönlendirir:
Diyagramdaki sayılar, çağıran bir yöntem asenkron yöntemi çağırdığında başlatılan aşağıdaki adımlara karşılık gelir.
Çağrı yapan yöntem,
GetUrlContentLengthAsynczaman uyumsuz yöntemini çağırır ve tamamlanmasını bekler.GetUrlContentLengthAsyncbir HttpClient örneği oluşturur ve bir web sitesinin içeriğini dize olarak indirmek için GetStringAsync zaman uyumsuz yöntemini çağırır.GetStringAsync'ın ilerlemesini askıya alan bir şey olur. Belki de bir web sitesinin indirilmesini veya başka bir engelleme etkinliğini beklemesi gerekir. Kaynakları engellemekten kaçınmak içinGetStringAsync, denetimi çağıranıGetUrlContentLengthAsync'e verir.GetStringAsync, Task<TResult> bir dize olduğu birTResultdöndürür veGetUrlContentLengthAsyncgörevigetStringTaskdeğişkenine atar. Görev,GetStringAsyncçağrısının devam eden işlemini, iş tamamlandığında gerçek bir metin değeri üretme taahhüdüyle temsil eder.getStringTaskhenüz beklenmediği için,GetUrlContentLengthAsyncGetStringAsyncsonucuna bağlı olmayan diğer çalışmalarla devam edebilir. Bu çalışma,DoIndependentWorkzaman uyumlu yöntemine yapılan bir çağrıyla temsil edilir.DoIndependentWork, işini yapıp çağıranına geri dönen zaman uyumlu bir metottur.GetUrlContentLengthAsync,getStringTask'den bir sonuç almadan gerçekleştirebileceği işi tükenir. sonrakiGetUrlContentLengthAsyncindirilen dizenin uzunluğunu hesaplamak ve döndürmek istiyor, ancak yöntem dizeye sahip olana kadar bu değeri hesaplayamaz.Bu nedenle,
GetUrlContentLengthAsyncilerleme durumunu askıya almak veGetUrlContentLengthAsyncadlı yönteme denetim vermek için bir await işleci kullanır.GetUrlContentLengthAsyncçağırana birTask<int>döndürür. Görev, indirilen dizenin uzunluğu olan bir tamsayı sonucu üretmeye yönelik bir vaattir.Uyarı
GetStringAsync(ve dolayısıylagetStringTask)GetUrlContentLengthAsyncbeklemeden önce tamamlanırsa, denetimGetUrlContentLengthAsync'te kalır. Zaman uyumsuz olarak adlandırılan işlemGetUrlContentLengthAsynctamamlandığında ve nihai sonucu beklemek zorunda olmadığında askıya alma vegetStringTasksonra geri dönmeGetUrlContentLengthAsyncgiderleri boşa gider.Çağırma yönteminin içinde işleme düzeni devam eder. Çağıran, bu sonucu beklemeden önce
GetUrlContentLengthAsyncsonucuna bağlı olmayan başka işler de yapabilir veya çağıran hemen bekler. Çağıran yöntemGetUrlContentLengthAsync'ı bekliyor veGetUrlContentLengthAsync,GetStringAsync'yi bekliyor.GetStringAsynctamamlanır ve bir dize sonucu üretir. Dize sonucu, beklediğiniz şekildeGetStringAsyncçağrısı tarafından döndürülmüyor. (Yöntemin 3. adımda zaten bir görev döndürdüğünü unutmayın.) Bunun yerine, dize sonucu yönteminin tamamlanmasını temsil eden görevde depolanırgetStringTask. await işlecigetStringTask'dan sonucu alır. Atama ifadesi, alınan sonucucontents'a atar.GetUrlContentLengthAsyncdize sonucuna sahip olduğunda, yöntemi dizenin uzunluğunu hesaplayabilir. ArdındanGetUrlContentLengthAsyncişi de tamamlanır ve bekleyen olay işleyicisi devam edebilir. Makalenin sonundaki tam örnekte, olay işleyicisinin uzunluk sonucunun değerini alıp yazdırdığını onaylayabilirsiniz. Zaman uyumsuz programlamada yeniyseniz, zaman uyumlu ve zaman uyumsuz davranış arasındaki farkı göz önünde bulundurmak için bir dakikanızı ayırın. Zaman uyumlu yöntem, çalışması tamamlandığında (5. adım) döndürür, ancak zaman uyumsuz yöntem, çalışması askıya alındığında bir görev değeri döndürür (3. ve 6. adım). Asenkron yöntem sonunda çalışmasını tamamladığında, görev tamamlanmış olarak işaretlenir ve varsa sonuç görevde depolanır.
API asenkron yöntemler
Eşzamansız programlamayı destekleyen GetStringAsync gibi yöntemleri nerede bulabileceğinizi merak ediyor olabilirsiniz. .NET Framework 4.5 veya üzeri ve .NET Core, async ve awaitile çalışan birçok üye içerir. Bunları üye adına eklenen "Async" soneki ve dönüş türüne Task veya Task<TResult> göre tanıyabilirsiniz. Örneğin, System.IO.Stream sınıfı, CopyToAsync, ReadAsyncve WriteAsync gibi yöntemlerin yanı sıra senkron yöntemler CopyTo, Readve Write'yı içerir.
Windows Çalışma Zamanı, Windows uygulamalarında async ve await ile kullanabileceğiniz birçok yöntem de içerir. Daha fazla bilgi için UWP geliştirme bağlamında İş Parçacığı oluşturma ve zaman uyumsuz programlama hakkında bölümüne, Windows Çalışma Zamanı'nın önceki sürümlerini kullanıyorsanız Zaman Uyumsuz programlama (Windows Mağazası uygulamaları) ve Hızlı Başlangıç: C# veya Visual Basic'de zaman uyumsuz API'leri çağırma bölümüne bakın.
Konular
Eşzamansız yöntemler bloklama yapmayan işlemler olarak tasarlanmıştır. Asenkron bir yöntemdeki await ifadesi, beklenen görev yürütülürken geçerli iş parçacığını engellemez. Bunun yerine, ifade yöntemin geri kalanını bir devam olarak kaydeder ve denetimi zaman uyumsuz yöntemin çağıranına döndürür.
async ve await anahtar sözcükleri fazladan iş parçacığı oluşturulmasına neden olmaz. Zaman uyumsuz yöntemler, kendi iş parçacıklarında çalışmadıkları için çok iş parçacıklı olmalarını gerektirmez. Bu yöntem geçerli eşitleme bağlamında çalışır ve yalnızca yöntem etkin olduğunda iş parçacığında zamanı kullanır. CPU'ya bağlı işi bir arka plan iş parçacığına taşımak için Task.Run kullanabilirsiniz, ancak arka plan iş parçacığı yalnızca sonuçların kullanılabilir olmasını bekleyen bir işlemde yardımcı olmaz.
Zaman uyumsuz programlamada, async tabanlı yaklaşım neredeyse her durumda mevcut yaklaşımlara tercih edilir. Özellikle, kod daha basit olduğundan ve yarış durumlarına karşı koruma sağlamanız gerekmediğinden, bu yaklaşım G/Ç'ye bağlı işlemler için BackgroundWorker sınıfına göre daha iyidir.
Task.Run yöntemiyle birlikte, zaman uyumsuz programlama, kodunuzu çalıştırmanın koordinasyon ayrıntılarını BackgroundWorker'nin iş parçacığı havuzuna aktardığı işlerden ayırdığı için, zaman uyumsuz programlama CPU'ya bağlı işlemler için Task.Run daha iyidir.
Asenkron ve await
async değiştiricisini kullanarak bir yöntemin zaman uyumsuz bir yöntem olduğunu belirtirseniz, aşağıdaki iki yeteneği etkinleştirmiş olursunuz.
İşaretlenmiş zamansız yöntem, askıya alma noktalarını belirtmek için await kullanabilir.
awaitişleci, derleyiciye, beklenen zaman uyumsuz işlem tamamlanana kadar zaman uyumsuz metodun bu noktadan sonra devam edemeyeceğini söyler. Bu arada denetim, zaman uyumsuz yöntemi çağıran kişiye geri döner.awaitifadesinde eş zamansız bir yöntemin askıya alınması, yöntemden çıkışı temsil etmez vefinallyblokları çalıştırmaz.İşaretlenmiş async metodu, kendisini çağıran yöntemler tarafından beklenebilir.
Zaman uyumsuz bir yöntem genellikle bir veya daha fazla await işleci içerir, ancak await ifadelerinin olmaması derleyici hatasına neden olmaz. Zaman uyumsuz bir yöntem bir askıya alma noktasını işaretlemek için await işleci kullanmıyorsa, async değiştiricisine rağmen zaman uyumlu bir yöntem olarak yürütülür. Derleyici, bu tür yöntemler için bir uyarı oluşturur.
async ve await bağlamsal anahtar sözcüklerdir. Daha fazla bilgi ve örnek için aşağıdaki makalelere bakın:
Dönüş türleri ve parametreleri
Asenkron bir yöntem genellikle bir Task veya Task<TResult>döndürür. Zaman uyumsuz bir yöntemin içinde, başka bir zaman uyumsuz yönteme yapılan çağrıdan döndürülen bir işleme bir await operatörü uygulanır.
Eğer yöntem, Task<TResult>türünde bir işleneni belirten bir return deyimi içeriyorsa, dönüş türü olarak TResult'ı belirtmelisiniz.
Yöntemin dönüş deyimi yoksa veya işlenen döndürmeyen bir return deyimi varsa dönüş türü olarak Task kullanırsınız.
Tür bir GetAwaiter yöntemi içeriyorsa, başka herhangi bir dönüş türü de belirtebilirsiniz.
ValueTask<TResult>, böyle bir türe örnektir.
System.Threading.Tasks.Extension NuGet paketinde kullanılabilir.
Aşağıdaki örnek, Task<TResult> veya Taskdöndüren bir yöntemi nasıl bildirip çağırabileceğinizi gösterir:
async Task<int> GetTaskOfTResultAsync()
{
int hours = 0;
await Task.Delay(0);
return hours;
}
Task<int> returnedTaskTResult = GetTaskOfTResultAsync();
int intResult = await returnedTaskTResult;
// Single line
// int intResult = await GetTaskOfTResultAsync();
async Task GetTaskAsync()
{
await Task.Delay(0);
// No return statement needed
}
Task returnedTask = GetTaskAsync();
await returnedTask;
// Single line
await GetTaskAsync();
Döndürülen her görev devam eden çalışmayı temsil eder. Görev, asenkron işlemin durumu hakkında bilgileri kapsüller ve nihayetinde ya işlemin nihai sonucunu ya da başarılı olmazsa ortaya çıkan istisnayı içerir.
Eş zamansız bir yöntemin void dönüş türü de olabilir. Bu dönüş türü öncelikle bir void dönüş türünün gerekli olduğu olay işleyicilerini tanımlamak için kullanılır. Zaman uyumsuz olay işleyicileri genellikle zaman uyumsuz programlar için başlangıç noktası görevi görür.
void dönüş türüne sahip asenkron bir yöntem beklenemez ve void döndüren bir yöntemi çağıran, yöntemin attığı özel durumları yakalayamaz.
Zaman uyumsuz bir yöntem içinde, ref veya out parametrelerini bildiremez, ancak böyle parametrelere sahip yöntemleri çağırabilir. Benzer şekilde, zaman uyumsuz bir yöntem başvuruya göre bir değer döndüremez, ancak referans dönüş değerine sahip yöntemleri çağırabilir.
Daha fazla bilgi ve örnek için bkz. Asenkron dönüş türleri (C#).
Windows Çalışma Zamanı programlamasında asenkron API'lerin, görevlere benzer şekilde aşağıdaki dönüş türlerinden biri bulunur:
- IAsyncOperation<TResult>, Task<TResult>'e karşılık gelir.
- IAsyncAction, Task'e karşılık gelir.
- IAsyncActionWithProgress<TProgress>
- IAsyncOperationWithProgress<TResult,TProgress>
Adlandırma kuralı
Kurala göre, sıkça beklenen türleri döndüren yöntemlerin adları "Async" ile bitmelidir (örneğin, Task, Task<T>, ValueTask, ValueTask<T>). Zaman uyumsuz bir işlem başlatan ve beklenebilir bir tür döndürmeyen yöntemlerin adları "Async" ile bitmemelidir. Ancak, bu yöntemin, işlemin sonucunu döndürmediğini veya fırlatmadığını belirtmek için "Begin", "Start" veya başka bir fiil ile başlayabilir.
Olay, temel sınıf veya arabirim sözleşmesinin farklı bir ad önerdiği kuralı yoksayabilirsiniz. Örneğin, OnButtonClickgibi yaygın olay işleyicilerini yeniden adlandırmamalısınız.
İlgili makaleler (Visual Studio)
| Başlık | Açıklama |
|---|---|
| Async ve await (C#) kullanarak birden çok web isteğini paralel olarak yapma | Aynı anda birkaç görev başlatmayı gösterir. |
| Zaman uyumsuz dönüş türleri (C#) | Asenkron yöntemlerin döndürebileceği türleri gösterir ve her türün hangi durumlarda uygun olduğunu açıklar. |
| Görevleri iptal etmek için bir sinyalleme mekanizması olarak iptal belirteci kullanın. | Asenkron çözümünüze aşağıdaki işlevselliğin nasıl ekleneceğini gösterir: - Görev listesini iptal etme (C#) - Bir süre sonra görevleri iptal etme (C#) - Zaman uyumsuz görevleri tamamlandıkça işle (C#) |
| Dosya erişimi için asenkron kullanma (C#) | Asenkron ve bekleme kullanarak dosyalara erişmenin faydalarını listeler ve gösterir. |
| Görev tabanlı eşzamanlı olmayan model (TAP) | Eşzamansız bir deseni açıklar. Desen, Task ve Task<TResult> türlerine dayanır. |
| Channel 9 'da Eşzamansız Videolar | Zaman uyumsuz programlama hakkında çeşitli videoların bağlantılarını sağlar. |
Ayrıca bkz.
- Async ve await ile zaman uyumsuz programlama
- Asenkron
- bekliyor