Aracılığıyla paylaş


.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. Asenkron işlemleri temsil etmek için kullanılan Task ad alanındaki Task<TResult> ve System.Threading.Tasks türlerini temel alır.

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, son eki Async olan bir yöntem gerektirir ve ayrıca bir veya daha fazla olay, olay işleyicisi temsilci türleri ve EventArg türetilmiş türler gerektirir. TAP'deki zaman uyumsuz yöntemler, Async, Task, Task<TResult> ve ValueTask gibi beklenebilir türler döndüren yöntemlerin adından sonra ValueTask<TResult> son ekini içerir. Örneğin, bir Get döndüren zaman uyumsuz bir işlem Task<String> olarak adlandırılabilir.GetAsync 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 fırlatmadığını belirtmek için adı Begin, Start veya başka bir fiil ile başlamalıdır.  

Bir TAP yöntemi, karşılık gelen zaman uyumlu yöntemin System.Threading.Tasks.Task veya tür System.Threading.Tasks.Task<TResult> döndürdüğüne bağlı olarak ya bir System.Threading.Tasks.Task ya da bir 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. out veya ref parametresi aracılığıyla döndürülecek tüm veriler, bunun yerine TResult tarafından döndürülen Task<TResult>'nin bir parçası olarak döndürülmeli ve birden fazla değere uyum sağlamak için bir demet veya özel bir veri yapısı kullanılmalıdır. Ayrıca, TAP yönteminin zaman uyumlu karşılığı bir CancellationToken parametresi sunmuyor olsa bile bir parametre eklemeyi 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 WhenAll ve WhenAny verilebilir 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.

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'yi temel alan zaman uyumsuz bir yöntem, örneğin, bağımsız değişkenleri doğrulama ve zaman uyumsuz işlemi başlatma gibi az miktarda işi zaman uyumlu olarak yaptıktan sonra, elde edilen görevi döndürebilir. Eşzamanlı olmayan yöntemin hızla yanıt verebilmesi için eşzamanlı çalışma en düşük seviyede tutulmalıdır. Hızlı iadenin nedenleri şunlardır:

  • Zaman uyumsuz yöntemler kullanıcı arabirimi (UI) iş parçacıklarından çağrılabilir ve uzun süre çalışan zaman uyumlu çalışmalar uygulamanın yanıt verme hızına zarar verebilir.

  • Aynı anda birden çok zaman uyumsuz yöntem başlatılabilir. Bu nedenle, zaman uyumsuz bir yöntemin zaman uyumlu bölümünde uzun süre çalışan herhangi bir çalışma, diğer zaman uyumsuz işlemlerin başlatılmasını geciktirerek eşzamanlılığın avantajlarını azaltabilir.

Bazı durumlarda, işlemi tamamlamak için gereken çalışma miktarı, işlemi zaman uyumsuz olarak başlatmak için gereken çalışma miktarından daha azdır. Okuma işleminin bellekte zaten arabelleğe alınmış veriler tarafından karşılanabildiği bir akıştan okumak, böyle bir senaryoya örnektir. Bu gibi durumlarda işlem zaman uyumlu bir şekilde tamamlanabilir ve zaten tamamlanmış bir görevi döndürebilir.

Özel durumlar

Zaman uyumsuz bir yöntem, yalnızca bir kullanım hatasına yanıt olarak zaman uyumsuz yöntem çağrısından atılacak bir özel durum oluşturmalıdır. Üretim kodunda hiçbir zaman kullanım hataları oluşmamalıdır. Ö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 tüm hatalar için, zaman uyumsuz bir yöntem çalıştırıldığında oluşan özel durumlar, zaman uyumsuz yöntem görev döndürülmeden önce zaman uyumlu bir şekilde tamamlansa bile döndürülen göreve atanmalıdır. Genellikle, 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 uyguladığınızda, zaman uyumsuz yürütmenin nerede gerçekleştiğini 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öntemiyle yürütülecek bir şey bile olmayabilir ve yalnızca sistemin başka bir yerinde bir koşulun meydana geldiğini temsil eden bir Task döndürebilir (örneğin, kuyruğa alınmış bir veri yapısına gelen verileri temsil eden bir görev).

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. Devamlılık kodunu oluşturan, bu kodun nerede yürütüleceği üzerinde 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ü TaskStatus numaralandırma tipi tarafından temsil edilir. Task ve Task<TResult> türlerinden türetilen türlerin köşe durumlarını desteklemek ve yapının zamanlamadan ayrılmasını sağlamak için, Task sınıfı bir Start yöntemi ortaya koyar. Halk Task oluşturucular tarafından oluşturulan görevler, yaşam döngülerine zamanlanmamış durumda başladıkları ve ancak bu örneklerde Created çağrıldıklarında zamanlandıkları için Start olarak adlandırılır.

Diğer tüm görevler, temsil ettikleri zaman uyumsuz işlemlerin zaten başlatıldığı ve görev durumlarının TaskStatus.Created dışında bir numaralandırma değeri olduğu anlamına gelen aktif durumda yaşam döngülerine başlar. 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, döndürmeden önce Start nesnesi üzerinde Task çağrısı yapması gerekir. TAP yönteminin kullanıcıları, döndürülen görevin etkin olduğunu güvenle varsayabilir ve TAP yönteminden döndürülen herhangi bir Start üzerinde Task çağırmayı denememelidirler. Start'nin etkin bir görevde çağrılması bir InvalidOperationException özel durumla sonuçlanır.

İptal (isteğe bağlı)

TAP'de iptal, hem zaman uyumsuz yöntem uygulayıcıları 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

Asenkron işlem, iptal istekleri için bu belirteci izler. bir iptal isteği alırsa, bu isteği yerine getirmek ve işlemi iptal etmek isteyebilir. İptal isteği, çalışmanın erken sona ermesine neden olursa, TAP yöntemi bir Canceled durumunda sona eren bir görev döndürür; bir sonuç mevcut değildir ve herhangi bir istisna fırlatılmaz. Durum Canceled, Faulted ve RanToCompletion durumlarıyla birlikte bir görevin son (tamamlanmış) durumu olarak kabul edilir. Bu nedenle, bir görev Canceled durumundaysa, IsCompleted özelliği true değerini döndürür. Görev Canceled durumunda tamamlandığında, devamı iptal etmek için bir NotOnCanceled devamlılık seçeneği belirtilmediyse, göreve kayıtlı olan tüm devamlılıklar zamanlanır veya yürütülür. Dil özelliklerini kullanarak eşzamanlı olmayan bir şekilde iptal edilen bir görevi bekleyen tüm kodlar çalışmaya devam eder, ancak bu özel durumdan türetilmiş bir OperationCanceledException veya özel durum alır. Wait ve WaitAll gibi yöntemler aracılığıyla, görev üzerinde zaman uyumlu olarak beklerken engellenen kod, bir istisna ile ç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, zaman uyumsuz işlem çalışırken iptal istenirse, zaman uyumsuz işlemin iptal isteğini kabul etmesi gerekmez. Geri dönen görev, yalnızca iptal isteğinin Canceled sonucu olarak işlemin sona ermesi durumunda bitmelidir. İptal istenirse ancak yine de bir sonuç veya özel durum oluşturulursa, görevin RanToCompletion veya Faulted durumunda bitmesi gerekir.

Öncelikli olarak 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 aşırı yüklemeler sağlamaktan kaçının; bu, çağırıcıya hedef yöntemin gerçekten iptal edilebilir olup olmadığını göstermek konusunda yardımcı olur. İptal istemeyen tüketici kodu, CancellationToken kabul eden bir yöntem çağırabilir ve bağımsız değişken değeri olarak None sağlar. None , işlevsel olarak varsayılan CancellationTokenile eşdeğerdir.

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

Bazı zaman uyumsuz işlemler ilerleme bildirimleri sağlamanın avantajıdır; bunlar genellikle bir kullanıcı arabirimini zaman uyumsuz işlemin ilerleme durumuyla ilgili bilgilerle güncelleştirmek için kullanılır.

TAP'te ilerleme, genellikle IProgress<T> adı verilen bir parametre olarak zaman uyumsuz yönteme geçirilen bir progress arabirimi aracılığıyla yönetilir. Zaman uyumsuz yöntem çağrıldığında ilerleme arabiriminin sağlanması, yanlış kullanımdan kaynaklanan yarış koşullarını ortadan kaldırmaya yardımcı olur (yani işlem başladıktan sonra yanlış kaydedilen olay işleyicileri güncelleştirmeleri kaçırabilir). Daha da önemlisi, ilerleme arabirimi, tüketen kod tarafından belirlenen farklı ilerleme uygulamalarını destekler. Örneğin, kullanıcı kod yalnızca en son ilerleme güncellemesi ile ilgilenebilir, tüm güncellemeleri arabelleğe almak isteyebilir, her güncelleme için bir eylem çağırmak isteyebilir veya çağırmanın belirli bir iş parçacığına yönlendirilip yönlendirilmediğini kontrol etmek 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 demet ile 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üne genellikle ProgressInfo son eklenir.

TAP uygulamaları, bir progress parametresini kabul eden aşırı yüklemeler sağlıyorsa, bağımsız değişkenin null olmasına izin vermelidir; bu durumda herhangi bir ilerleme bildirilmez. 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 tüketicisinin bilgileri en iyi nasıl ve nerede işleyeceğini belirlemesine olanak tanır. Örneğin, ilerleme örneği geri çağırmaları hazırlamayı ve yakalanan eşitleme bağlamında olayları tetiklemeyi seçebilir.

IProgress<T> implementasyonları

.NET, Progress<T>'i uygulayan IProgress<T> sınıfını sağlar. 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 her ilerleme güncellemesini bildirdiğinde tetiklenen bir ProgressChanged olayı kullanıma sunar. ProgressChanged örneği oluşturulduğunda yakalanan SynchronizationContext nesnesi üzerinde Progress<T> olayı tetiklenir. Eşzamanlama bağlamı mevcut değilse, iş parçacığı havuzunu hedefleyen varsayılan bir bağlam kullanılır. İşlemciler bu olayla kaydedilebilir. 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. olay işleyicileri yürütülürken zaman uyumsuz işlemin gecikmesini önlemek için ilerleme güncelleştirmeleri zaman uyumsuz olarak oluşturulur. Başka bir IProgress<T> uygulama farklı semantikler uygulamayı seçebilir.

Sağlanacak 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  

TAP uygulaması iptali veya ilerleme durumunu destekliyor ancak 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  

TAP uygulaması hem iptali hem de ilerlemeyi destekliyorsa, dört farklı fonksiyon aşırı yüklemesini de kullanıma sunabilir. 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 None parametresi için CancellationToken ya da varsayılan bir cancellationToken ve null parametresi için progress geçebilirler.

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

Eğer iptal veya ilerlemeyi isteğe bağlı hale getirmek için birden çok aşırı yükleme sunmayı düşünüyorsanız, iptal veya ilerlemeyi desteklemeyen aşırı yüklemeler, iptal için None veya ilerleme için null parametrelerini destekleyen aşırı yüklemeye geçmiş gibi davranmalıdır.

Başlık Açıklama
Asenkron Programlama Desenleri Zaman uyumsuz işlemler gerçekleştirmek için üç deseni tanıtır: Görev Tabanlı Zaman Uyumsuz Desen (TAP), Zaman Uyumsuz Programlama Modeli (APM) ve Olay Tabanlı Zaman Uyumsuz Desen (EAP).
Görev Tabanlı Asenkron Tasarımın Uygulanması Üç şekilde Görev Tabanlı Zaman Uyumsuz Desenin (TAP) nasıl uygulanacağı açıklanır: Visual Studio'da C# ve Visual Basic derleyicilerini kullanarak, manuel olarak veya derleyici ve manuel yöntemlerin bir kombinasyonu aracılığıyla.
Görev Tabanlı Zaman Uyumsuz Deseni Kullanma Engelleme olmadan beklemeyi başarmak için görevleri ve geri çağırmaları nasıl kullanabileceğinizi açıklar.
Diğer Asenkron Desenler ve Türlerle Etkileşim Zaman Uyumsuz Programlama Modeli (APM) ve Olay Tabanlı Zaman Uyumsuz Deseni (EAP) uygulamak için Görev Tabanlı Zaman Uyumsuz Desenin (TAP) nasıl kullanılacağını açıklar.