2009-04-24 37 views
6

Ana iş parçacığı üzerinde yürütülecek kod bölümünü nasıl zorlayabilirim?Ana iş parçacığı üzerinde kod yürütme zorlaması

Ben zamanlarda ana iş parçacığı olmayan bir iplikten gösterilecek bir özel oluşturulan ileti kutusu var: Ben bilmek istiyorum neden

budur. Ancak, ileti kutusu yapıcısı çağrıldığında, bir "InvalidOperationException" deyimi alıyorum "Çağıran iş parçacığı STA olmalı, çünkü birçok UI bileşeni bunu gerektirir." Bu mantıklı, UI öğeleri ana iş parçacığı üzerinde ele alınması gerekiyor.

MessageBox.ShowMessage (...) işlevi, özel ileti kutunun bir örneğini oluşturan ve bunu gösteren statik bir işlevdir. Mesaj kutusunun oluşturulması ve ana konu üzerinde gösterilmesini zorlayacak olan ShowMessage'a koyduğum bir şey var mı? Kodumun başka bir yerinde, benzer sorunları işlemek için Control.BeginInvoke kullanıyorum, ancak statik bir işlev olduğundan, BeginInvoke'u çağırmam için zaten mevcut bir UI öğesi yok.

MessageBox.ShowMessage öğesini Control.BeginInvoke ile çağırmalı mıyım? ShowMessage içinde çağrılacak BeginInvoke (veya bazı eşdeğer) tercih ederim.

cevap

5

birkaç seçenek var burada:

  • ikinci iplik STA yapmak (yalnızca kendi Thread için yapabilir - değil ThreadPool parçacığı için) - .SetApartmentState(ApartmentState.STA);
  • aracılığıyla bkz SynchronizationContext.Current olmayan ise boş; eğer öyleyse, (WPF için geçerli olmayabilir - Emin% 100 değilim) bir ISynchronizeInvoke örneği olarak form/kontrol geçmektedir Send/Post
  • kullanmak
+0

Listelediğiniz ilk seçeneği uygulama hakkında bilgi veren bir bağlantınız var mı? – w4g3n3r

+0

İş parçacığı başlatılmadan önce Thread.SetApartmentState() öğesini çağırın. – itowlson

+0

İş parçacığı oluştururken, (düzenlenmiş) yanıtta gösterildiği gibi .SetApartmentState öğesini çağırın. İpliği oluştururken daha fazla yardıma ihtiyacınız varsa lütfen bize bildirin. –

5

Sizin düşünce doğru - sırayla için Düzgün çalışmasını sağlayın, ana iş parçacığı denilen almak için ihtiyacınız olacak.

En basit yol? Ana formunuzu başlattığınızda, ShowMessage() çağrınıza görünür bir statik değişkende bir referans kaydedin. Doğrudan mesaj kutusu gösteren yerine

if(myForm.InvokeRequired) 
{ 
    myForm.Invoke(() => ShowMessage(arg1,arg2,arg3)); 
    return; 
} 
.... other code here.... 
+3

Aslında bir değişkene ihtiyaç duymayabilir - WPF'de Application.Current.MainWindow'u WinForms uygulamasında Application.OpenForms koleksiyonundan bir pencere kullanabilir. – itowlson

1

sadece bir ileti kutusu görüntülemek için ana iş parçacığı sinyalleri ana iş parçacığı, bir mesaj göndermek: Ardından, ShowMessage standardını yapabilirsiniz.

+0

+1 bu aslında çok daha az müdahaleci IMO – Rick

+0

Bunu nasıl yapacağınıza dair bir örnek verebilir misiniz? – Brabbeldas

İlgili konular