ProgramlamaMasaüstü Geliştirici (WinForms, VB.NET)

Visual Basic'te olay kuyrukları (event queue) ve asenkron çağrıların nasıl gerçekleştirildiği ve çeşitli yöntemlerin (DoEvents, BackgroundWorker, Async/Await) farklılıklarının neler olduğu?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Visual Basic'te asenkron çağrılar ve olay işleme genellikle programın türüne ve dilin sürümüne bağlı olarak farklı şekillerde uygulanır. Klasik WinForms uygulamalarında VB.NET'te olay kuyrukları (event queue) genellikle Application.DoEvents() çağrısı ile işlenir. Bu yöntem olay işleyicisinin "kontrolü bırakmasına" olanak tanır, böylece diğer mesajlar ana iş parçacığını engellemeden işlenebilir:

While loading Application.DoEvents() 'Kullanıcı etkileşimlerine UI'nin tepki vermesini sağlar End While

VB.NET ile .NET'te görevleri asenkron olarak yürütmek için kullanılan yöntemler:

  • BackgroundWorker — UI iş parçacığı ile güvenli etkileşime sahip ayrı bir iş parçacığında uzun süreli işlemleri gerçekleştirmek için WinForms bileşeni.
  • Async/Await anahtar kelimeleri — .NET 4.5'te ortaya çıkan modern bir asenkronluk sistemi, asenkron kod yazmayı "senkron gibi" kolaylaştırır:
Public Async Function LoadDataAsync() As Task Dim result As String = Await GetWebDataAsync() TextBox1.Text = result End Function

Farklılıklar:

  • DoEvents, UI mesaj kuyruğunu sadece işler ve yeni iş parçacıkları yaratmaz.
  • BackgroundWorker, işi ayrı bir iş parçacığına aktarır ve UI iş parçacığına güvenli dönüş için bir olaya sahiptir.
  • Async/Await, asenkronluğu gerçekleştirirken kontrolün UI iş parçacığına geri dönüşünü kapsüller.

Kapalı bir soru.

Bir dosyayı diskinizden yüklerken ve ProgressBar'ı güncellerken DoEvents kullanmanın tehlikesi nedir?

Cevap: DoEvents, kontrolü diğer Windows olaylarına geçici olarak aktarıyor ama iş parçacığını serbest bırakmıyor. Eğer ağır döngülerde (örneğin büyük bir dosya okuma sırasında kullanıcı arayüzünü güncellemeye çalışırken) kullanılırsa, beklenmedik hatalar meydana gelebilir: kullanıcı ve fare olayları işlenir, bu da işleme tekrar başlamaya veya uygulamanın "takılmasına" yol açabilir. Ağır yüklenme bekleniyorsa, BackgroundWorker veya Task kullanılmalıdır.

Yanlış yaklaşıma örnek:

For i = 1 To 1000000 ProgressBar1.Value = i / 10000 Application.DoEvents() 'Ana iş parçacığını serbest bırakmaz! Next

Hikaye

Pratikte bir örnekte: VB6 uygulamasını VB.NET'e taşırken, dosya okuma sürecinde ilerleme göstergesini güncellemek için uzun bir döngü içinde DoEvents kullanılmıştır. Sonuç olarak arayüz "takıldı": kullanıcı "Aç" butonuna bir kez daha tıklarsa, dosya okuma süreci tekrar başlar, bu da veri bozulmasına ve uygulamanın çökmesine yol açtı.

Hikaye

Bir finans yazılımı projesinde bir çalışan, BackgroundWorker ile tanışmadığı için döngü içinde grafiği DoEvents ile güncellemeye karar verdi. Büyük bir veri setini güncellerken uygulama takılmaya başladı ve sonuç olarak Windows mesaj kuyruklarının aşırı yüklenmesi nedeniyle "uçtu".

Hikaye

Async/Await ile asenkron çağrı kullanıldı, uzun süren işlemlerin "sıcak" UI iş parçacığında Await Task.Run(...) olmadan başlatılamayacağını anlamadan. Sonuç: arayüz tıklamalara tepki vermedi ve ilerleme çubuğu güncellenmedi, çünkü uzun yöntem yine ana iş parçacığında çalışıyordu.