Share via


Olay Tabanlı Zaman Uyumsuz Deseni Uygulama

Fark edilebilir gecikmelere neden olabilecek bazı işlemleri olan bir sınıf yazıyorsanız, Olay Tabanlı Zaman Uyumsuz Deseni uygulayarak zaman uyumsuz işlevsellik vermeyi göz önünde bulundurun.

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ı Zaman Uyumsuz Deseni uygulayan bir örnek için bkz . Nasıl yapılır: Olay Tabanlı Zaman Uyumsuz Deseni Destekleyen Bir Bileşen Uygulama.

Basit zaman uyumsuz işlemler için bileşeni uygun bulabilirsiniz BackgroundWorker . hakkında BackgroundWorkerdaha fazla bilgi için bkz . Nasıl yapılır: Arka Planda İşlem Çalıştırma.

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 istemcilerine ve zaman uyumsuz işlemler için kullanılabilen nesnelere gerek WaitHandleIAsyncResult yoktur; yani yoklama ve WaitAll veya WaitAny istemci tarafından derlenmesi gerekir.

  • 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. Özellikle uygun olan, istemcilerin bir yöntemi çağırdığı ve tamamlandıktan sonra bildirildiği ve başka müdahale gerekmediği işlemlerdir. 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

Zaman uyumsuz bir karşılık sağlamak istediğiniz her zaman uyumlu MethodName yöntemi için:

Ş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, MethodName Async ile aynı ancak adlı userStateek nesne değerli parametresiyle 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. Yalnızca kendi örneğini AsyncCompletedEventArgs kullanın.

      Not

      Temsilciyi ve AsyncCompletedEventArgs türleri yeniden kullanmak mümkün ve uygun olduğunda, son derece kabul edilebilir. Bu durumda, belirli bir temsilci olduğundan ve AsyncCompletedEventArgs tek bir yönteme bağlı olmayacağı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 zaman uyumsuz işlemler bekleyen birden çok 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
Sınıfın tamamında Bir Zaman Uyumsuz İşlem Sub MethodNameAsyncCancel(ByVal userState As Object) Sub MethodNameAsyncCancel()
Sınıfında Birden Çok Zaman Uyumsuz İşlem Sub CancelAsync(ByVal userState As Object) Sub CancelAsync()

C#

Desteklenen Birden Çok Eşzamanlı İşlem Aynı Anda Yalnızca Bir İşlem
Sınıfın tamamında Bir Zaman Uyumsuz İşlem void MethodNameAsyncCancel(object userState); void MethodNameAsyncCancel();
Sınıfında Birden Çok Zaman Uyumsuz İş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ümlere ek zaman uyumsuz işlemler eklenmesini bekliyorsanız, tanımlamak CancelAsyncdaha 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öndürülecektir ve işlem iptal edilebilir veya olmayabilir. MethodName Completed olayının olay işleyicisinde MethodName CompletedEventArgs 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 MethodName Async yönteminden bir özel durum yakalamadan MethodNameAsync yönteminin çalışıp çalışmadığını belirlemesine olanak tanır.

Olay Tabanlı Zaman Uyumsuz Deseni IsBusyUygulamak 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ı Zaman Uyumsuz Desen, bunu yapmak için bir kılavuz sağlar.

  • İsteğe bağlı olarak, zaman uyumsuz işlem tarafından tetiklenecek ve uygun iş parçacığında çağrılacak bir olay tanımlayın. Nesnesi, ProgressChangedEventArgs 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);

    • Sınıfın tek bir zaman uyumsuz işlemi varsa MethodNameProgressChanged .

    bu adlandırma seçimi, İptali İsteğe Bağlı Olarak Destekle bölümünde açıklandığı gibi iptal yöntemi için yapılan 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.

Desteklediği zaman uyumsuz yöntemlerin sayısından bağımsız olarak sınıf için yalnızca bir ProgressChanged veya MethodNameProgressChanged olayı olduğunu unutmayın. İstemcilerin, birden çok eşzamanlı işlemdeki ilerleme güncelleştirmelerini ayırt etmek için MethodNameAsync yöntemlerine geçirilen nesnesini kullanması userState 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 MethodName Async 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.

MethodNameProgressChanged olayının yaptığı gibi "tüm işlemler" üzerinde artımlı sonuçlar döndürmek için aynı olayla ilgili bir sorun olmadığından, bu çözüm özellikle tek bir zaman uyumsuz işlem sınıfına uygulanır.

Homojen Artımlı Sonuçlarla Çoklu İş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.

  • Bu yöntemin artımlı sonuç verilerini işlemek için her zaman uyumsuz yöntem için uygun olan ayrı bir MethodNameProgressChanged olayı EventArgs 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

ve ref kullanımı out genel olarak .NET'te önerilmez olsa da, mevcut olduklarında uyulması gereken kurallar şunlardır:

MethodName zaman uyumlu bir yöntem verilip verilmedi:

  • outMethodName parametreleri MethodName Async'in parçası olmamalıdır. Bunun yerine, MethodName içindeki parametre eşdeğeriyle aynı ada sahip MethodNameCompletedEventArgs'in parçası olmalıdır (daha uygun bir ad olmadığı sürece).

  • refMethodName parametreleri MethodName Async'in bir parçası olarak ve MethodName'deki parametre eşdeğeriyle aynı ada sahip MethodNameCompletedEventArgs'ın bir parçası olarak görünmelidir (daha uygun bir ad olmadığı sürece).

Örneğin, verilen:

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 bkz.