Aracılığıyla paylaş


Olay Tabanlı Zaman Uyumsuzluk Desenini Uygulama

Fark edilebilir gecikmelere yol açabilecek bazı işlemleri olan bir sınıf yazıyorsanız, Olay Tabanlı Asenkron Deseni uygulayarak asenkron işlevsellik eklemeyi düşünün.

Olay Tabanlı Zaman Uyumsuz Desen, zaman uyumsuz özelliklere sahip bir sınıfı paketlemek için standartlaştırılmış bir yol sağlar. gibi AsyncOperationManageryardımcı sınıflarla uygulanırsa sınıfınız ASP.NET, Konsol uygulamaları ve Windows Forms uygulamaları dahil olmak üzere herhangi bir uygulama modeli altında doğru şekilde çalışır.

Olay Tabanlı Asenkron Deseni uygulayan bir örnek için, Olay Tabanlı Asenkron Deseni Destekleyen Bir Bileşeni Nasıl Uygularım bölümüne bakın.

Basit zaman uyumsuz işlemler için BackgroundWorker bileşenini uygun bulabilirsiniz. BackgroundWorker hakkında daha fazla bilgi için, Nasıl Yapılır: Bir İşlemi Arka Planda Çalıştırma bölümüne bakın.

Aşağıdaki listede, bu konuda ele alınan Olay Tabanlı Zaman Uyumsuz Desenin özellikleri açıklanmaktadır.

  • Olay Tabanlı Zaman Uyumsuz Deseni Uygulama Fırsatları

  • Zaman Uyumsuz Yöntemleri Adlandırma

  • İsteğe bağlı olarak İptal Desteği

  • İsteğe bağlı olarak IsBusy Özelliğini Destekleme

  • İsteğe bağlı olarak İlerleme Durumu Raporlama desteği sağlayın

  • İsteğe bağlı olarak Artımlı Sonuçları Döndürme desteği sağlayın

  • Yöntemlerde Out ve Ref Parametrelerini İşleme

Olay Tabanlı Zaman Uyumsuz Deseni Uygulama Fırsatları

Aşağıdaki durumlarda Olay Tabanlı Zaman Uyumsuz Deseni uygulamayı göz önünde bulundurun:

  • Sınıfınızın istemcilerinin, zaman uyumsuz işlemler için WaitHandle ve IAsyncResult nesnelerinin kullanılabilir olmasına ihtiyacı yoktur; yani yoklama ve WaitAll veya WaitAny istemci tarafından oluşturulmalıdır.

  • Zaman uyumsuz işlemlerin istemci tarafından tanıdık olay/temsilci modeliyle yönetilmesini istiyorsunuz.

Herhangi bir işlem zaman uyumsuz bir uygulama için bir adaydır, ancak uzun gecikme süreleri olmasını beklediğiniz işlemler göz önünde bulundurulmalıdır. İstemcilerin bir yöntemi çağırdığı, tamamlandıktan sonra bilgilendirildiği ve başka müdahale gerektirmeyen işlemler özellikle uygundur. Ayrıca sürekli çalışan ve istemcileri ilerleme durumu, artımlı sonuçlar veya durum değişikliklerini düzenli aralıklarla bilgilendiren işlemler de uygundur.

Olay Tabanlı Zaman Uyumsuz Desenin ne zaman desteklenmesine karar verme hakkında daha fazla bilgi için bkz. Olay Tabanlı Zaman Uyumsuz Desenin Ne Zaman Uygulanacaklarına Karar Verme.

Zaman Uyumsuz Yöntemleri Adlandırma

Her eşzamanlı MethodName yöntemi için eşzamanlı olmayan bir karşılık sağlamak istiyorsanız:

Şu şekilde bir MethodNameAsync yöntemi tanımlayın:

  • void döndürür.

  • MethodName yöntemiyle aynı parametreleri alır.

  • Birden çok çağrı kabul eder.

İsteğe bağlı olarak, MethodNameAsync ile aynı olan fakat ek bir nesne değerli parametre içeren bir MethodNameAsync aşırı yüklemesi tanımlayın. Yönteminizin birden çok eşzamanlı çağrısını yönetmeye hazırsanız bunu yapın. Bu durumda, yöntemin userState çağrılarını ayırt etmek için değer tüm olay işleyicilerine geri teslim edilir. Bunu daha sonra almak üzere kullanıcı durumunu depolamak için bir yer olarak yapmayı da seçebilirsiniz.

Her ayrı MethodNameAsync yöntemi imzası için:

  1. Aşağıdaki olayı yöntemiyle aynı sınıfta tanımlayın:

    Public Event MethodNameCompleted As MethodNameCompletedEventHandler
    
    public event MethodNameCompletedEventHandler MethodNameCompleted;
    
  2. Aşağıdaki temsilciyi ve AsyncCompletedEventArgstanımlayın. Bunlar büyük olasılıkla sınıfın kendisi dışında, ancak aynı ad alanında tanımlanacaktır.

    Public Delegate Sub MethodNameCompletedEventHandler( _
        ByVal sender As Object, _
        ByVal e As MethodNameCompletedEventArgs)
    
    Public Class MethodNameCompletedEventArgs
        Inherits System.ComponentModel.AsyncCompletedEventArgs
    Public ReadOnly Property Result() As MyReturnType
    End Property
    
    public delegate void MethodNameCompletedEventHandler(object sender,
        MethodNameCompletedEventArgs e);
    
    public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
    {
        public MyReturnType Result { get; }
    }
    
    • Alanlar veri bağlamayı engellediğinden MethodNameCompletedEventArgs sınıfının üyelerini alanlar değil salt okunur özellikler olarak kullanıma sunduğundan emin olun.

    • Sonuç üretmeyen yöntemler için türetilmiş sınıf AsyncCompletedEventArgstanımlamayın. Sadece AsyncCompletedEventArgs'nin kendi örneğini kullanın.

      Uyarı

      Mümkün ve uygun olduğunda, temsilci ve AsyncCompletedEventArgs türlerini yeniden kullanmak son derece kabul edilebilir. Bu durumda, belirli bir temsilci ve AsyncCompletedEventArgs tek bir yönteme bağlı olmadığından adlandırma, yöntem adıyla tutarlı olmayacaktır.

İsteğe bağlı olarak İptal Desteği

Sınıfınız zaman uyumsuz işlemlerin iptalini destekleyecekse, iptal işlemi aşağıda açıklandığı gibi istemciye açıklanmalıdır. İptal desteğinizi tanımlamadan önce ulaşılması gereken iki karar noktası vardır:

  • Gelecekte beklenen eklemeler de dahil olmak üzere, sınıfınızın iptali destekleyen yalnızca bir zaman uyumsuz işlemi var mı?
  • İptali destekleyen asenkron işlemler, birden fazla bekleyen işlemi destekleyebilir mi? Başka bir ifadeyle MethodNameAsync yöntemi bir parametre alır ve herhangi bir userState parametrenin bitmesi beklenmeden önce birden çok çağrıya izin verir mi?

İptal yönteminizin imzasının ne olması gerektiğini belirlemek için aşağıdaki tabloda yer alan bu iki sorunun yanıtlarını kullanın.

Visual Basic

Desteklenen Birden Çok Eşzamanlı İşlem Aynı Anda Yalnızca Bir İşlem
Tüm sınıfta bir asenkron işlem Sub MethodNameAsyncCancel(ByVal userState As Object) Sub MethodNameAsyncCancel()
Sınıfta Birden Çok Asenkron İşlem Sub CancelAsync(ByVal userState As Object) Sub CancelAsync()

C# (programlama dili)

Desteklenen Birden Çok Eşzamanlı İşlem Aynı Anda Yalnızca Bir İşlem
Tüm sınıfta bir asenkron işlem void MethodNameAsyncCancel(object userState); void MethodNameAsyncCancel();
Sınıfta Birden Çok Asenkron İşlem void CancelAsync(object userState); void CancelAsync();

Yöntemini tanımlarsanız, istemcilerin CancelAsync(object userState) yalnızca tek bir zaman uyumsuz yöntemin tüm çağrıları arasında değil, nesne üzerinde çağrılan tüm zaman uyumsuz yöntemler arasında ayrım yapabilmelerini sağlamak için durum değerlerini seçerken dikkatli olmaları gerekir.

Tek zaman uyumsuz işlem sürümünü MethodNameAsyncCancel olarak adlandırma kararı, Visual Studio'nun IntelliSense'i gibi bir tasarım ortamında yöntemi daha kolay keşfedebilmeyi temel alır. Bu, ilgili üyeleri gruplandırır ve zaman uyumsuz işlevsellikle ilgisi olmayan diğer üyelerden ayırır. Sonraki sürümlerde ek zaman uyumsuz işlemler eklenmesi beklentiniz varsa, CancelAsync tanımlamak daha iyidir.

Aynı sınıfta yukarıdaki tablodan birden çok yöntem tanımlamayın. Bu mantıklı olmayacaktır veya sınıf arabirimini yöntemlerin çoğalmasıyla karmaşık hale getirecektir.

Bu yöntemler genellikle hemen döner ve işlemin iptali gerçekleşebilir veya gerçekleşmeyebilir. MethodNameCompleted olayının olay işleyicisinde MethodNameCompletedEventArgs nesnesi, istemcilerin iptal işleminin gerçekleşip gerçekleşmediğini belirlemek için kullanabileceği bir Cancelled alan içerir.

Olay Tabanlı Zaman Uyumsuz Deseni Uygulamak için En İyi Yöntemler bölümünde açıklanan iptal semantiğine uyun.

İsteğe bağlı olarak IsBusy Özelliğini Destekleme

Sınıfınız birden çok eşzamanlı çağrıyı desteklemiyorsa, bir IsBusy özelliği kullanıma sunmanız gerekir. Bu, geliştiricilerin MethodNameAsync yönteminden bir özel durum yakalamadan MethodNameAsync yönteminin çalışıp çalışmadığını belirlemesine olanak tanır.

IsBusy Uygulamak için En İyi Yöntemler bölümünde açıklanan semantiklere uyun.

İsteğe bağlı olarak İlerleme Durumu Raporlama desteği sağlayın

Zaman uyumsuz bir işlemin, işlemi sırasında ilerleme durumunu raporlaması sık sık tercih edilir. Olay Tabanlı Asenkron Desen, bunu yapmak için bir kılavuz sağlar.

  • Zaman uyumsuz işlem tarafından tetiklenip uygun iş parçacığında çağrılacak bir olayı isteğe bağlı olarak tanımlayın. ProgressChangedEventArgs nesnesi, 0 ile 100 arasında olması beklenen tamsayı değerli bir ilerleme göstergesi taşır.

  • Bu olayı aşağıdaki gibi adlandırın:

    • ProgressChanged sınıfta birden çok zaman uyumsuz işlem varsa (veya gelecekteki sürümlerde birden çok zaman uyumsuz işlem içerecek şekilde büyümesi bekleniyorsa);

    • MethodName tek bir asenkron işlemi varsa ProgressChanged sınıfında yapılacaktır.

    Bu adlandırma seçimi, İsteğe Bağlı Destekleme İptali bölümünde açıklandığı gibi iptal yöntemi için yapılan seçimle paraleldir.

Bu olay temsilci imzasını ProgressChangedEventHandler ve sınıfını ProgressChangedEventArgs kullanmalıdır. Alternatif olarak, etki alanına özgü bir ilerleme göstergesi sağlanabilirse (örneğin, bir indirme işlemi için okuma baytları ve toplam baytlar) türetilmiş bir sınıfı ProgressChangedEventArgstanımlamanız gerekir.

Unutmayın ki desteklediği eşzamansız yöntemlerin sayısından bağımsız olarak sınıf için yalnızca bir ProgressChanged veya MethodNameProgressChanged olayı vardır. İstemcilerin, birden çok eşzamanlı işlemdeki ilerleme güncellemelerini ayırt etmek için userState nesnesini, MethodNameAsync yöntemlerine geçirmesi beklenir.

Birden çok işlemin ilerlemeyi desteklediği ve her birinin ilerleme durumu için farklı bir gösterge döndürdüğü durumlar olabilir. Bu durumda tek bir ProgressChanged olay uygun değildir ve birden çok ProgressChanged olayı desteklemeyi düşünebilirsiniz. Bu durumda, her MethodNameAsync yöntemi için MethodNameProgressChanged adlandırma desenini kullanın.

Olay Tabanlı Zaman Uyumsuz Deseni Uygulamak için En İyi Yöntemler açıklanan ilerleme raporlama semantiğine uyun.

İsteğe bağlı olarak Artımlı Sonuçları Döndürme desteği sağlayın

Bazen zaman uyumsuz bir işlem tamamlanmadan önce artımlı sonuçlar döndürebilir. Bu senaryoya destek vermek için kullanılabilecek bir dizi seçenek vardır. Bazı örnekler aşağıda verilmiştir.

Tek işlemli Sınıf

Sınıfınız yalnızca tek bir zaman uyumsuz işlemi destekliyorsa ve bu işlem artımlı sonuçlar döndürebiliyorsa:

  • ProgressChangedEventArgs Artımlı sonuç verilerini taşımak için türünü genişletin ve bu genişletilmiş verilerle bir MethodNameProgressChanged olayı tanımlayın.

  • Raporlanan artımlı bir sonuç olduğunda bu MethodNameProgressChanged olayını yükseltin.

Bu çözüm, yalnızca tek bir zaman uyumsuz işlem sınıfı için geçerlidir, çünkü MethodNameProgressChanged olayında olduğu gibi "tüm işlemler" üzerinde artımlı sonuçlar döndürmek için aynı olayın ortaya çıkmasında herhangi bir sorun yoktur.

Eşit Artımlı Sonuçlar ile Birden Çok İşlem Sınıfı

Bu durumda sınıfınız, her biri artımlı sonuçlar döndürebilen birden çok zaman uyumsuz yöntemi destekler ve bu artımlı sonuçların tümü aynı veri türüne sahiptir.

Aynı EventArgs yapı tüm artımlı sonuçlar için çalışacağından, tek işlemli sınıflar için yukarıda açıklanan modeli izleyin. ProgressChanged Birden çok zaman uyumsuz yönteme uygulandığından MethodNameProgressChanged olayı yerine bir olay tanımlayın.

Heterojen Artımlı Sonuçlarla Çoklu İşlem Sınıfı

Sınıfınız birden çok zaman uyumsuz yöntemi destekliyorsa ve her biri farklı türde veriler döndüriyorsa şunları yapmalısınız:

  • Artımlı sonuç raporlamanızı ilerleme durumu raporlamanızdan ayırın.

  • Her bir asenkron yöntemin artımlı sonuç verilerini işlemek için uygun tanımlayarak ayrı bir MethodNameEventArgs olayı tanımlayın.

Olay Tabanlı Zaman Uyumsuz Deseni Uygulamak için En İyi Yöntemler bölümünde açıklandığı gibi uygun iş parçacığında bu olay işleyicisini çağırın.

Yöntemlerde Out ve Ref Parametrelerini İşleme

out ve ref kullanımı genel olarak .NET'te önerilmez olsa da, mevcut olduklarında aşağıdaki kurallara uyulmalıdır.

Verilen bir zaman uyumlu yöntem MethodName:

  • out MethodName parametreleri MethodNameAsync'in parçası olmamalıdır. Bunun yerine, MethodName'deki parametre karşılığı ile aynı ada sahip CompletedEventArgs'in parçası olmalıdır (daha uygun bir ad olmadığı sürece).

  • ref MethodName için parametreler, MethodNameAsync'in bir parçası olarak ve MethodNameCompletedEventArgs içinde aynı ada sahip parametre eşdeğeri olarak görünmelidir (daha uygun bir ad olmadığı sürece).

Örneğin, şu durumlarda:

Public Function MethodName(ByVal arg1 As String, ByRef arg2 As String, ByRef arg3 As String) As Integer
public int MethodName(string arg1, ref string arg2, out string arg3);

Zaman uyumsuz yönteminiz ve AsyncCompletedEventArgs sınıfı şu şekilde görünür:

Public Sub MethodNameAsync(ByVal arg1 As String, ByVal arg2 As String)

Public Class MethodNameCompletedEventArgs
    Inherits System.ComponentModel.AsyncCompletedEventArgs
    Public ReadOnly Property Result() As Integer
    End Property
    Public ReadOnly Property Arg2() As String
    End Property
    Public ReadOnly Property Arg3() As String
    End Property
End Class
public void MethodNameAsync(string arg1, string arg2);

public class MethodNameCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
    public int Result { get; };
    public string Arg2 { get; };
    public string Arg3 { get; };
}

Ayrıca bakınız