.NET'te görev tabanlı zaman uyumsuz desen (TAP): Giriş ve genel bakış

.NET'te görev tabanlı zaman uyumsuz desen, yeni geliştirme için önerilen zaman uyumsuz tasarım desenidir. Zaman uyumsuz işlemleri temsil etmek için kullanılan ad alanında System.Threading.Tasks ve Task<TResult> türlerini temel alırTask.

Adlandırma, parametreler ve dönüş türleri

TAP, bir zaman uyumsuz işlemin başlangıcını ve tamamlanmasını temsil etmek için tek bir yöntem kullanır. Bu, hem Zaman Uyumsuz Programlama Modeli (APM veya IAsyncResult) deseni hem de Olay Tabanlı Zaman Uyumsuz Desen (EAP) ile karşıttır. APM için Begin ve End yöntemleri gerekir. EAP, soneki Async olan bir yöntem gerektirir ve ayrıca bir veya daha fazla olay, olay işleyicisi temsilci türleri ve EventArgtüretilmiş türler gerektirir. TAP'deki zaman uyumsuz yöntemler, , Task<TResult>, ValueTaskve ValueTask<TResult>gibi Taskbeklenebilir türler döndüren yöntemlerin işlem adından sonraki son eki içerirAsync. Örneğin, döndüren zaman uyumsuz Get bir işlem olarak adlandırılabilirGetAsync.Task<String> EAP yöntemi adını Async içeren bir sınıfa tap yöntemi ekliyorsanız bunun yerine son eki TaskAsync kullanın. Örneğin, sınıfın zaten bir GetAsync yöntemi varsa adını GetTaskAsynckullanın. Bir yöntem zaman uyumsuz bir işlem başlatır ancak beklenebilir bir tür döndürmezse, bu yöntemin işlemin sonucunu döndürmediğini veya oluşturmadığını önermek için adı , Startveya başka bir fiil ile Beginbaşlamalıdır.  

TAP yöntemi, karşılık gelen zaman uyumlu yöntemin System.Threading.Tasks.Task void veya tür TResultdöndürdüğüne bağlı olarak bir veya System.Threading.Tasks.Task<TResult>döndürür.

Tap yönteminin parametreleri, zaman uyumlu karşılık geleninin parametreleriyle eşleşmeli ve aynı sırada sağlanmalıdır. out Ancak ve ref parametreleri bu kuraldan muaftır ve tamamen kaçınılmalıdır. Veya ref parametresi aracılığıyla out döndürülecek tüm veriler bunun yerine tarafından Task<TResult>döndürülenlerin TResult bir parçası olarak döndürülmelidir ve birden çok değere uyum sağlamak için bir tanımlama grubu veya özel veri yapısı kullanmalıdır. Ayrıca, TAP yönteminin zaman uyumlu karşılığı bir parametre sunmuyor olsa bile parametre eklemeyi CancellationToken göz önünde bulundurun.

Yalnızca görevlerin oluşturulmasına, işlemesine veya birleşimine (yöntemin zaman uyumsuz amacının yöntem adında veya yöntemin ait olduğu türün adında net olduğu) ayrılmış yöntemlerin bu adlandırma düzenine uyması gerekmez; bu tür yöntemler genellikle birleştirici olarak adlandırılır. Birleştiricilere örnek olarak ve verilebilir WhenAll ve , Görev Tabanlı Zaman Uyumsuz Deseni Kullanma makalesinin Yerleşik Görev Tabanlı Birleştiricileri Kullanma bölümünde ele alınmaktadır.WhenAny

TAP söz diziminin, Zaman Uyumsuz Programlama Modeli (APM) ve Olay Tabanlı Zaman Uyumsuz Desen (EAP) gibi eski zaman uyumsuz programlama desenlerinde kullanılan söz diziminden nasıl farklı olduğunu gösteren örnekler için bkz . Zaman Uyumsuz Programlama Desenleri.

Zaman uyumsuz işlem başlatma

TAP tabanlı bir zaman uyumsuz yöntem elde edilen görevi döndürmeden önce, az miktarda bir işi (bağımsız değişkenleri doğrulamak ya da zaman uyumsuz işlemi başlatmak gibi) zaman uyumlu olarak yapabilir. Zaman uyumsuz yöntemin çabuk dönmesini sağlamak için zaman uyumlu iş olabildiğince az tutulmalıdır. Hızlı iadenin nedenleri şunlardır:

  • Zaman uyumsuz yöntemler kullanıcı arabirimi (UI) iş parçacıkları tarafında çağırılabilirler, ve herhangi bir uzun süre çalışan zaman uyumlu iş uygulamanın yanıt verme becerisine zarar verebilir.

  • Birden çok zaman uyumsuz yöntem eşzamanlı başlatılabilir. Bu nedenle, bir zaman uyumsuz yöntemin herhangi bir uzun süren zaman uyumlu bölümü diğer zaman uyumsuz işlemlerin başlamasını geciktirerek eşzamanlılığın yararlarını azaltabilir.

Bazı durumlarda, işlemi tamamlamak için gereken iş, işlemi zaman uyumsuz olarak başlatmak için gereken işten daha azdır. Okuma işleminin bellekte zaten arabelleğe alınmış veri ile tamamlanabileceği bir akıştan okumak bu duruma bir örnektir. Bu gibi durumlarda, işlem zaman uyumlu olarak tamamlanabilir ve zaten tamamlanmış bir görevi döndürebilir.

Özel durumlar

Bir zaman uyumsuz yöntem, zaman uyumsuz yöntem çağrısının dışına atılacak bir özel durumu sadece bir kullanım hatasına yanıt olarak harekete geçirmelidir. Kullanım hataları asla üretim kodunda gerçekleşmemelidir. Örneğin, yöntemin bağımsız değişkenlerinden biri olarak null başvuru (Nothing Visual Basic'te) geçirmek hata durumuna neden oluyorsa (genellikle bir ArgumentNullException özel durumla gösterilir), null başvurunun hiçbir zaman geçirilmediğini sağlamak için çağıran kodu değiştirebilirsiniz. Diğer bütün hatalar için, görev döndürülene kadar zaman uyumsuz yöntem zaman uyumlu olarak tamamlansa bile, zaman uyumsuz yöntem yürütülüyorken oluşan özel durumlar döndürülen göreve atanmalıdır. Genel olarak, bir görev en fazla bir özel durum içerir. Ancak, görev birden çok işlemi (örneğin, ) temsil ederse, WhenAlltek bir görevle birden çok özel durum ilişkilendirilebilir.

Hedef ortam

Bir TAP yöntemi oluştururken, zaman uyumsuz yürütülmenin nerede olacağını belirleyebilirsiniz. İş yükünü iş parçacığı havuzunda yürütmeyi, zaman uyumsuz G/Ç kullanarak (işlemin yürütülmesinin çoğunluğu için bir iş parçacığına bağlı olmadan) uygulamayı, belirli bir iş parçacığında çalıştırmayı (ui iş parçacığı gibi) veya herhangi bir sayıda olası bağlamı kullanmayı seçebilirsiniz. TAP yönteminin yürütülecek bir şeyi bile olmayabilir ve yalnızca sistemin başka bir yerinde (örneğin, kuyruğa alınmış bir veri yapısına gelen verileri temsil eden bir görev) bir koşulun oluşumunu temsil eden bir döndürebilir Task .

TAP yöntemini çağıran, sonuçta elde edilen görevi zaman uyumlu bir şekilde bekleyerek TAP yönteminin tamamlanmasını beklemeyi engelleyebilir veya zaman uyumsuz işlem tamamlandığında ek (devamlılık) kodu çalıştırabilir. Devam kodunun yaratıcısı kodun nerede çalışacağına dair denetime sahiptir. Devamlılık kodunu açıkça, sınıfındaki Task yöntemlerle (örneğin, ContinueWith) veya örtük olarak, devamlılıkların üzerine kurulu dil desteğini kullanarak oluşturabilirsiniz (örneğin, await C#'de, Await Visual Basic'te, AwaitValue F# dilinde).

Görev durumu

Task sınıfı, zaman uyumsuz işlemler için bir yaşam döngüsü sağlar ve bu döngü sabit listesi tarafından TaskStatus temsil edilir. ve Task<TResult>türlerinden Task türetilen türlerin köşe örneklerini desteklemek ve derlemenin zamanlamadan Task ayrılmasını desteklemek için, sınıfı bir Start yöntemi kullanıma sunar. Ortak Task oluşturucular tarafından oluşturulan görevler, yaşam döngülerine zamanlanmamış Created durumda başladığı ve yalnızca bu örneklerde çağrıldığında Start zamanlandığı için soğuk görevler olarak adlandırılır.

Diğer tüm görevler yaşam döngülerine sık erişimli durumda başlar; bu, temsil ettikleri zaman uyumsuz işlemlerin zaten başlatıldığı ve görev durumlarının dışında TaskStatus.Createdbir numaralandırma değeri olduğu anlamına gelir. TAP yöntemlerinden döndürülen tüm görevler etkinleştirilmelidir. TAP yöntemi, döndürülecek görevin örneğini oluşturmak için bir görevin oluşturucusunu dahili olarak kullanıyorsa, TAP yönteminin döndürmeden önce nesne üzerinde Task çağrısı Start yapması gerekir. BIR TAP yönteminin tüketicileri, döndürülen görevin etkin olduğunu ve tap yönteminden döndürülen herhangi Task bir görev üzerinde çağırmayı Start denememesi gerektiğini güvenle varsayabilir. Etkin bir görevde çağrılması Start bir InvalidOperationException özel durumla sonuç alır.

İptal (isteğe bağlı)

TAP kullanırken, iptal etmek hem zaman uyumsuz yöntem oluşturucuları hem de zaman uyumsuz yöntem tüketicileri için isteğe bağlıdır. İşlem iptale izin veriyorsa, bir iptal belirteci (CancellationToken örnek) kabul eden zaman uyumsuz yöntemin aşırı yüklemesini ortaya çıkarır. Kurala göre parametresi olarak adlandırılır cancellationToken.

public Task ReadAsync(byte [] buffer, int offset, int count,
                      CancellationToken cancellationToken)
Public Function ReadAsync(buffer() As Byte, offset As Integer,
                          count As Integer,
                          cancellationToken As CancellationToken) _
                          As Task

Zaman uyumsuz işlem iptal istekleri için bu belirteci izler. Eğer iptal isteği alırsa, bu isteği dikkate alarak işlemi iptal etmeyi seçebilir. İptal isteği çalışmanın erken sona ermesiyle sonuçlanırsa, TAP yöntemi durumla Canceled biten bir görev döndürür; kullanılabilir bir sonuç yoktur ve özel durum oluşturmaz. DurumCanceled, ve RanToCompletion durumlarıyla Faulted birlikte bir görevin son (tamamlandı) durumu olarak kabul edilir. Bu nedenle, bir görev durumundaysa Canceled , IsCompleted özelliği döndürür true. Bir görev durumunda tamamlandığında Canceled , devamı geri çevirmek için gibi NotOnCanceled bir devamlılık seçeneği belirtilmediği sürece, göreve kayıtlı tüm devamlılıklar zamanlanır veya yürütülür. Dil özelliklerini kullanarak zaman uyumsuz olarak iptal edilen bir görevi bekleyen tüm kodlar çalışmaya devam eder, ancak ondan türetilen bir OperationCanceledException veya özel durum alır. gibi yöntemler Wait aracılığıyla görev beklerken zaman uyumlu olarak engellenen kod ve WaitAll bir özel durumla çalışmaya devam eder.

İptal belirteci, belirteci kabul eden TAP yöntemi çağrılmadan önce iptal isteğinde bulunduysa, TAP yöntemi bir Canceled görev döndürmelidir. Ancak, eğer zaman uyumsuz işlem yürütülüyorken bir iptal istenirse, zaman uyumsuz işlem iptal isteğini kabul etmek zorunda değildir. Döndürülen görev yalnızca iptal isteğinin Canceled sonucu olarak işlemin sona ermesi durumunda sona ermelidir. İptal istenirse ancak yine de bir sonuç veya özel durum oluşturulursa, görevin veya Faulted durumunda bitmesi RanToCompletion gerekir.

en başta iptal edilme özelliğini kullanıma sunmak isteyen zaman uyumsuz yöntemler için, iptal belirtecini kabul etmeyen bir aşırı yükleme sağlamanız gerekmez. İptal edilemeyen yöntemler için iptal belirteci kabul eden bir aşırı yükleme sağlamayın; bu çağırana hedef yöntemin iptal edilip edilemez olduğunu belirtmeye yardımcı olur. İptal isteğinde bulunmayan tüketici kodu, bağımsız değişken değeri olarak ve CancellationToken kabul eden ve sağlayan None bir yöntemi çağırabilir. None , işlevsel olarak varsayılan CancellationTokenile eşdeğerdir.

İlerleme raporlama (isteğe bağlı)

Bazı zaman uyumsuz işlemler ilerleme bildirimlerinden faydalanır; bunlar genel olarak kullanıcı arayüzünü zaman uyumsuz işlemin ilerlemesi ile ilgili bilgiyle güncelleştirmekte kullanılır.

TAP'de ilerleme, genellikle adlı progressbir IProgress<T> parametre olarak zaman uyumsuz yönteme geçirilen bir arabirim aracılığıyla işlenir. Zaman uyumsuz yöntem çağırıldığında ilerleme arabirimini sağlamak yanlış kullanım nedeniyle ortaya çıkan yarış durumlarını engellemeye yardımcı olur (yanlış kayıt olan olay işleyicilerinin işlem başladıktan sonra güncellemeleri kaçırabilmesi). Daha da önemlisi, ilerleme arabirimi ilerlemenin tüketici kodunda belirlendiği üzere farklı uygulamalarını destekleyebilir. Örneğin, tüketen kod yalnızca en son ilerleme güncelleştirmesi ile ilgilenebilir veya tüm güncelleştirmeleri arabelleğe almak isteyebilir ya da her güncelleştirme için bir eylem çağırmak veya çağırmanın belirli bir iş parçacığına göre sıralanıp sıralanmadığını denetlemek isteyebilir. Tüm bu seçenekler, belirli bir tüketicinin ihtiyaçlarına göre özelleştirilmiş, arabirimin farklı bir uygulaması kullanılarak elde edilebilir. İptalde olduğu gibi, TAP uygulamaları yalnızca API ilerleme bildirimlerini destekliyorsa bir IProgress<T> parametre sağlamalıdır.

Örneğin, bu makalenin ReadAsync önceki bölümlerinde açıklanan yöntem, ara ilerleme durumunu şu ana kadar okunan bayt sayısı biçiminde bildirebiliyorsa, ilerleme geri çağırması bir IProgress<T> arabirim olabilir:

public Task ReadAsync(byte[] buffer, int offset, int count,
                      IProgress<long> progress)
Public Function ReadAsync(buffer() As Byte, offset As Integer,
                          count As Integer,
                          progress As IProgress(Of Long)) As Task

Bir FindFilesAsync yöntem, belirli bir arama desenini karşılayan tüm dosyaların listesini döndürürse, ilerleme geri araması tamamlanan çalışma yüzdesi ve geçerli kısmi sonuç kümesini tahmin edebilir. Bu bilgiler bir tanımlama grubuyla birlikte sağlanabilir:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
            string pattern,
            IProgress<Tuple<double,
            ReadOnlyCollection<List<FileInfo>>>> progress)
Public Function FindFilesAsync(pattern As String,
                               progress As IProgress(Of Tuple(Of Double, ReadOnlyCollection(Of List(Of FileInfo))))) _
                               As Task(Of ReadOnlyCollection(Of FileInfo))

veya API'ye özgü bir veri türüyle:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
    string pattern,
    IProgress<FindFilesProgressInfo> progress)
Public Function FindFilesAsync(pattern As String,
                               progress As IProgress(Of FindFilesProgressInfo)) _
                               As Task(Of ReadOnlyCollection(Of FileInfo))

İkinci durumda, özel veri türü genellikle ile ProgressInfoson eklenmiştir.

TAP uygulamaları parametre progress kabul eden aşırı yüklemeler sağlarsa, bağımsız değişkenin olmasına nullizin vermelidir. Bu durumda ilerleme bildirilmemelidir. TAP uygulamaları ilerleme durumunu nesneye Progress<T> zaman uyumlu olarak bildirmelidir ve bu da zaman uyumsuz yöntemin hızla ilerlemeyi sağlamasına olanak tanır. Ayrıca, ilerleme durumunun tüketicisinin bilgileri en iyi nasıl ve nerede işleyeceğini belirlemesine de olanak tanır. Örneğin, ilerleme örneği geri aramaları yönlendirmeyi ve yakalanan bir eşitleme bağlamında olay çağırmayı seçebilir.

IProgress<T> uygulamaları

.NET, öğesini uygulayan sınıfını IProgress<T>sağlarProgress<T>. Progress<T> sınıfı aşağıdaki gibi bildirilir:

public class Progress<T> : IProgress<T>  
{  
    public Progress();  
    public Progress(Action<T> handler);  
    protected virtual void OnReport(T value);  
    public event EventHandler<T>? ProgressChanged;  
}  

Örneği Progress<T> , zaman uyumsuz işlem bir ilerleme güncelleştirmesi bildirdiği her durumda tetiklenen bir olayı kullanıma sunar ProgressChanged . Olay ProgressChanged , örnek örneği oluşturulurken yakalanan nesnede SynchronizationContextProgress<T> oluşturulur. Eğer hiçbir eşitleme bağlamı kullanılabilir değilse, iş parçacığı havuzunu hedefleyen bir varsayılan bağlam kullanılır. İşleyiciler bu olay ile kayıtlı olabilir. Kolaylık sağlamak için oluşturucuya Progress<T> tek bir işleyici de sağlanabilir ve olay için ProgressChanged bir olay işleyicisi gibi davranır. İlerleme güncelleştirmeleri zaman uyumsuz işlemi olay işleyicileri yürütülürken geciktirmemek için zaman uyumsuz olarak harekete geçirilir. Başka bir IProgress<T> uygulama farklı semantikler uygulamayı seçebilir.

Sağlayabilecek aşırı yüklemeleri seçme

Bir TAP uygulaması hem isteğe bağlı CancellationToken hem de isteğe bağlı IProgress<T> parametreleri kullanıyorsa, dört adede kadar aşırı yükleme gerektirebilir:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
public Task MethodNameAsync(…, IProgress<T> progress);
public Task MethodNameAsync(…,
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken cancellationToken) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task
Public MethodNameAsync(…, cancellationToken As CancellationToken,
                       progress As IProgress(Of T)) As Task  

Ancak birçok TAP uygulaması iptal veya ilerleme özellikleri sağlamadığından tek bir yöntem gerektirir:

public Task MethodNameAsync(…);  
Public MethodNameAsync(…) As Task  

Eğer bir TAP uygulaması ya iptal ya da ilerleme destekliyorsa ama ikisini birden desteklemiyorsa, iki aşırı yükleme sağlayabilir:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
  
// … or …  
  
public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken) As Task  
  
' … or …  
  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task  

Eğer bir TAP uygulaması hem iptal hem de ilerleme destekliyorsa, tüm dört aşırı yüklemeyi ortaya çıkarabilir. Ancak, yalnızca aşağıdaki ikisini sağlayabilir:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…,
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken,
                       progress As IProgress(Of T)) As Task  

Eksik olan iki ara bileşimi telafi etmek için geliştiriciler parametre ve nullprogress parametre için cancellationToken varsayılan CancellationToken bir geçiş None yapabilir.

TAP yönteminin her kullanımının iptali veya ilerlemeyi desteklemesini bekliyorsanız, ilgili parametreyi kabul etmeyen aşırı yüklemeleri atabilirsiniz.

İptal veya ilerleme durumunu isteğe bağlı hale getirmek için birden çok aşırı yüklemeyi kullanıma sunma kararı alırsanız, iptali veya ilerlemeyi desteklemeyen aşırı yüklemeler, iptal için veya null bunları destekleyen aşırı yüklemeye ilerlemek üzere geçmiş None gibi davranmalıdır.

Ünvan Açıklama
Zaman Uyumsuz Programlama Desenleri Zaman uyumsuz işlemler gerçekleştirmek için üç desen tanıtır: Görev-tabanlı Zaman Uyumsuz Desen (TAP), Zaman Uyumsuz Programlama Modeli (APM) ve Olay-tabanlı Uyumsuz Desen (EAP).
Görev Tabanlı Zaman Uyumsuz Deseni Uygulama Görev-tabanlı Zaman Uyumsuz Desen (TAP) uygulamak için üç yol açıklar: Visual Studio içindeki C# ve Visual Basic derleyicilerini kullanarak, el yöntemi ile, veya derleyici ve el yönteminin bir kombinasyonu ile.
Görev Tabanlı Zaman Uyumsuz Desen Kullanma Engellemeden beklemeyi görevler ve geri aramalar kullanarak nasıl kullanacağınızı açıklar.
Diğer Zaman Uyumsuz Desen ve Türlerle Birlikte Çalışma Zaman Uyumsuz Programlama Modeli (APM) ve Olay-tabanlı Zaman Uyumsuz Model (EAP) uygulamak için Görev-tabanlı Zaman Uyumsuz Model'in nasıl kullanılacağını açıklar.