Aracılığıyla paylaş


Olay Tabanlı Zaman Uyumsuz Deseni Uygulamak için En İyi Yöntemler

Olay Tabanlı Eşzamansız Desen, tanıdık olay ve temsilci semantiğiyle, sınıflarda eşzamansız davranışı kullanıma sunmanın etkili bir yolunu sağlar. Olay Tabanlı Zaman Uyumsuz Desen uygulamak için bazı belirli davranış gereksinimlerini izlemeniz gerekir. Aşağıdaki bölümlerde, Olay Tabanlı Zaman Uyumsuz Deseni izleyen bir sınıf uygularken dikkate almanız gereken gereksinimler ve yönergeler açıklanmaktadır.

Genel bakış için bkz. Olay Tabanlı Asenkron Modelin Uygulanması.

Gerekli Davranış Garantileri

Olay Tabanlı Zaman Uyumsuz Deseni uygularsanız, sınıfınızın düzgün davranmasını ve sınıfınızın istemcilerinin bu tür davranışlara güvenebilmesini sağlamak için bir dizi garanti sağlamanız gerekir.

Tamamlanma

Başarılı bir tamamlama, hata veya iptal işlemi gerçekleştirdiğinizde her zaman MethodNameCompleted olay işleyicisini çağırın. Uygulamalar hiçbir zaman boşta kaldıkları ve tamamlamanın hiçbir zaman gerçekleşmediği bir durumla karşılaşmamalıdır. Bu kuralın bir istisnası, zaman uyumsuz işlemin kendisinin asla tamamlanmayacak şekilde tasarlanmış olmasıdır.

Tamamlanmış Olay ve EventArgs

Her ayrı MethodNameAsync yöntemi için aşağıdaki tasarım gereksinimlerini uygulayın:

  • yöntemiyle aynı sınıfta bir MethodNameCompleted olayı tanımlayın.

  • EventArgs sınıfından türetilen MethodNameCompleted olayı için, ona eşlik eden bir AsyncCompletedEventArgs sınıfı ve temsilci tanımlayın. Varsayılan sınıf adı MethodNameCompletedEventArgs biçiminde olmalıdır.

  • EventArgs sınıfının MethodName yönteminin dönüş değerlerine özgü olduğundan emin olun. sınıfını kullandığınızda, geliştiricilerin EventArgs sonucu atamasını hiçbir zaman gerektirmemelisiniz.

    Aşağıdaki kod örneği sırasıyla bu tasarım gereksiniminin iyi ve kötü bir şekilde uygulanmasını gösterir.

// Good design
private void Form1_MethodNameCompleted(object sender, xxxCompletedEventArgs e)
{
    DemoType result = e.Result;
}

// Bad design
private void Form1_MethodNameCompleted(object sender, MethodNameCompletedEventArgs e)
{
    DemoType result = (DemoType)(e.Result);
}
  • EventArgs döndüren yöntemler için bir void sınıf tanımlamayın. Bunun yerine AsyncCompletedEventArgs sınıfının bir örneğini kullanın.

  • MethodNameCompleted olayını her zaman tetiklediğinizden emin olun. Bu olay başarıyla tamamlandığında, bir hatada veya iptalde tetiklenmelidir. Uygulamalar hiçbir zaman boşta kaldıkları ve tamamlamanın hiçbir zaman gerçekleşmediği bir durumla karşılaşmamalıdır.

  • Zaman uyumsuz işlemde oluşan özel durumları yakaladığınızdan ve yakalanan özel durumu Error özelliğine atadığınızdan emin olun.

  • Görev tamamlanırken bir hata oluştuysa sonuçlara erişilmemesi gerekir. Error özelliği null olmadığında, EventArgs yapısındaki herhangi bir özelliğe erişimin bir özel durum tetiklediğinden emin olun. Bu doğrulamayı gerçekleştirmek için RaiseExceptionIfNecessary yöntemini kullanın.

  • Zaman aşımını bir hata olarak modelle. Zaman aşımı oluştuğunda, MethodNameCompleted olayını tetikleyin ve TimeoutException değerini Error özelliğine atayın.

  • Sınıfınız birden çok eşzamanlı çağrıyı destekliyorsa , MethodNameCompleted olayının uygun userSuppliedState nesneyi içerdiğinden emin olun.

  • MethodNameCompleted olayının uygun iş parçacığında ve uygulama yaşam döngüsünde uygun zamanda tetiklendiğinden emin olun. Daha fazla bilgi için İş Parçacıkları ve Bağlamlar bölümüne bakın.

İşlemleri Aynı Anda Yürütme

  • Sınıfınız birden çok eşzamanlı çağrıyı destekliyorsa, nesne değerli durum parametresini veya adlı görev kimliğini alan MethodNameuserSuppliedState aşırı yüklemesini tanımlayarak geliştiricinin her çağrıyı ayrı olarak izlemesini sağlayın. Bu parametre her zaman MethodNameAsync yönteminin imzasında son parametre olmalıdır.

  • Sınıfınız nesne değerli durum parametresini veya görev kimliğini alan MethodNameAsync aşırı yüklemesini tanımlıyorsa, bu görev kimliğiyle işlemin ömrünü izlemeyi ve tamamlama işleyicisine geri sağladığınızdan emin olun. Yardımcı olabilecek yardımcı sınıflar vardır. Eşzamanlılık yönetimi hakkında daha fazla bilgi için bkz: Olay Tabanlı Zaman Uyumsuz Desenini Destekleyen Bir Bileşeni Uygulama.

  • Sınıfınız MethodNameAsync yöntemini durum parametresi olmadan tanımlıyorsa ve birden çok eşzamanlı çağrıyı desteklemiyorsa, önceki MethodNameAsync çağrısı tamamlanmadan önce MethodNameAsync çağırma girişiminin bir InvalidOperationExceptiontetiklediğinden emin olun.

  • Genel olarak, parametresi olmayan MethodNameuserSuppliedState yöntemi birden çok kez çağrılırsa, bekleyen birden çok işlem olması için özel durum oluşturmayın. Sınıfınız bu durumu açıkça işleyemediğinde bir özel durum oluşturabilirsiniz, ancak geliştiricilerin bu ayırt edilemez geri çağırmaları işleyebileceğini varsayalım

Sonuçlara Erişme

İlerleme Durumu Raporlama

  • Mümkünse ilerleme raporlamayı destekleyin. Bu, geliştiricilerin sınıfınızı kullanırken daha iyi bir uygulama kullanıcı deneyimi sağlamasına olanak tanır.

  • ProgressChanged veya MethodNameProgressChanged olayı uygularsanız, işlemin MethodNameCompleted olayı oluşturulduktan sonra belirli bir zaman uyumsuz işlem için böyle bir olay tetiklemediğinden emin olun.

  • Standart ProgressChangedEventArgs dolduruluyorsa, ProgressPercentage değerinin her zaman yüzde olarak yorumlanabileceğinden emin olun. Yüzdenin doğru olması gerekmez, ancak bir yüzdeyi temsil etmelidir. İlerleme raporlama ölçütünüzün yüzde dışında bir değer olması gerekiyorsa, ProgressChangedEventArgs sınıfından bir sınıf türetin ve ProgressPercentage'i 0'da bırakın. Yüzde dışında bir raporlama ölçümü kullanmaktan kaçının.

  • ProgressChanged Olayın uygun iş parçacığında ve uygulama yaşam döngüsünde uygun zamanda tetiklendiğinden emin olun. Daha fazla bilgi için İş Parçacıkları ve Bağlamlar bölümüne bakın.

IsBusy Uygulaması

  • Sınıfınız birden çok eşzamanlı çağrıyı destekliyorsa bir IsBusy özelliğini kullanıma sunmayın. Örneğin, XML Web hizmeti proxy'leri, zaman uyumsuz yöntemlerin birden çok eşzamanlı çağrısını desteklediklerinden bir IsBusy özelliğini açığa çıkarmaz.

  • Özelliğin IsBusytrueAsync yöntemi çağrıldıktan sonra ve MethodNameCompleted olayı tetiklenmeden önce döndürülmesi gerekir. Aksi takdirde false geri döndürmelidir. BackgroundWorker ve WebClient bileşenleri, bir IsBusy özelliği kullanıma sunan sınıflara örnektir.

İptal

  • Mümkünse iptali destekleyin. Bu, geliştiricilerin sınıfınızı kullanırken daha iyi bir uygulama kullanıcı deneyimi sağlamasına olanak tanır.

  • İptal durumunda, Cancelled nesnesinde AsyncCompletedEventArgs bayrağını ayarlayın.

  • Sonucuna erişme girişiminin işlemin iptal edildiğine dair bir InvalidOperationException ifadeye neden olduğundan emin olun. Bu doğrulamayı gerçekleştirmek için AsyncCompletedEventArgs.RaiseExceptionIfNecessary yöntemini kullanın.

  • İptal yöntemine yapılan çağrıların her zaman başarılı bir şekilde sonuçlandığından ve hiçbir zaman istisna tetiklemediğinden emin olun. Genel olarak, istemciye herhangi bir zamanda bir işlemin gerçekten iptal edilebilir olup olmadığı bildirilmez ve daha önce verilen bir iptal işleminin başarılı olup olmadığı bildirilmez. Ancak, uygulama tamamlanma durumuna katıldığı için, bir iptal başarılı olduğunda uygulamaya her zaman bildirim gönderilir.

  • İşlem iptal edildiğinde MethodNameCompleted olayını tetikler.

Hatalar ve Özel Durumlar

  • Zaman uyumsuz işlemde oluşan özel durumları yakalayın ve özelliğinin AsyncCompletedEventArgs.Error değerini bu özel durum olarak ayarlayın.

İş Parçacığı Yönetimi ve Bağlamlar

Sınıfınızın doğru işlemi için, istemcinin olay işleyicilerinin ASP.NET ve Windows Forms uygulamaları dahil olmak üzere verilen uygulama modeli için uygun iş parçacığında veya bağlamda çağrılmış olması kritik önem taşır. Zaman uyumsuz sınıfınızın herhangi bir uygulama modeli altında doğru şekilde davranmasını sağlamak için iki önemli yardımcı sınıf sağlanır: AsyncOperation ve AsyncOperationManager.

AsyncOperationManager bir yöntemi sağlar. CreateOperationBu yöntem bir AsyncOperationdöndürür. MethodNameAsync yönteminiz CreateOperation çağrılarını yapar ve sınıfınız, döndürülen AsyncOperation öğesini, asenkron görevinin süresini izlemek amacıyla kullanır.

İlerleme durumunu, artımlı sonuçları ve tamamlanmayı istemciye bildirmek için Post üzerinde OperationCompleted ve AsyncOperation yöntemlerini çağırın. AsyncOperation , istemcinin olay işleyicilerine yönelik çağrıları uygun iş parçacığına veya bağlama göre sıralamaktan sorumludur.

Uyarı

Uygulama modelinin ilkesine açıkça karşı çıkmak istiyorsanız ancak Yine de Olay Tabanlı Zaman Uyumsuz Deseni kullanmanın diğer avantajlarından yararlanmak istiyorsanız bu kuralları aşabilirsiniz. Örneğin, Windows Forms'da çalışan bir sınıfın serbest iş parçacıklı olmasını isteyebilirsiniz. Geliştiriciler örtük kısıtlamaları anladığı sürece ücretsiz iş parçacıklı bir sınıf oluşturabilirsiniz. Konsol uygulamaları, Post çağrılarının yürütülmesini eşitlemez. Bu, ProgressChanged olayların sırasız bir şekilde tetiklenmesine neden olabilir. Eğer Post çağrılarının serileştirilmiş bir şekilde yürütülmesini istiyorsanız, bir System.Threading.SynchronizationContext sınıfı uygulayın ve yükleyin.

Asenkron işlemlerinizi etkinleştirmek için AsyncOperation ve AsyncOperationManager kullanma hakkında daha fazla bilgi için bkz Nasıl yapılır: Olay Tabanlı Zaman Uyumsuz Deseni Destekleyen Bir Bileşen Uygulama.

Yönergeler

  • İdeal olarak, her yöntem çağrısı diğerlerinden bağımsız olmalıdır. Paylaşılan kaynaklarla çağrıları birleştirmekten kaçınmanız gerekir. Kaynaklar çağrılar arasında paylaşılacaksa, uygulamanızda uygun bir eşitleme mekanizması sağlamanız gerekir.

  • İstemcinin eşitleme gerçekleştirmesini gerektiren tasarımlar önerilmez. Örneğin, genel statik nesneyi parametre olarak alan zaman uyumsuz bir yönteminiz olabilir; böyle bir yöntemin birden çok eşzamanlı çağrıları veri bozulmasına veya kilitlenmelere neden olabilir.

  • Birden fazla çağrı aşırı yüklemesiyle (userState imzada) bir yöntem uygularsanız, sınıfınızın kullanıcı durumları veya görev kimlikleri ile bunlara karşılık gelen bekleyen işlemlerin bir koleksiyonunu yönetmesi gerekir. Çeşitli çağrılar koleksiyondaki nesneleri ekleyip kaldırdığından lock bu koleksiyon bölgelerle userState korunmalıdır.

  • Uygun ve elverişli yerlerde CompletedEventArgs sınıflarını yeniden kullanmayı göz önünde bulundurun. Bu durumda, belirli bir temsilci ve EventArgs tür tek bir yönteme bağlı olmadığından adlandırma yöntem adıyla tutarlı değildir. Ancak, geliştiricileri üzerindeki bir özellikten alınan değeri atamaya EventArgs zorlamak hiçbir zaman kabul edilemez.

  • Eğer Component öğesinden türetilen bir sınıf oluşturuyorsanız, kendi SynchronizationContext sınıfınızı uygulamayın ve kurmayın. Kullanılan bileşenleri değil uygulama modelleri denetler SynchronizationContext .

  • Herhangi bir türde çoklu iş parçacığı kullandığınızda, potansiyel olarak kendinizi çok ciddi ve karmaşık hatalara maruz bırakırsınız. Çoklu iş parçacığı kullanımı kullanan bir çözüm uygulamadan önce bkz. Yönetilen İş Parçacığı Oluşturma En İyi Yöntemleri.

Ayrıca bakınız