2010-05-04 24 views

cevap

13

(basitleştirme öncesinde)

bir kullanıcı arayüzü ipliği (Win bu Kontroller anlamına gelir), çeşitli kullanıcı arayüzü nesneleri oluşturmak için kullanılan bir tek Diş Daire ipliğidir. Sözleşme ve kural gereği, bir Denetim, yalnızca'u oluşturmak için kullanılan iş parçacığı içinden erişilebilir; Aksi takdirde, beklenmedik sonuçlar doğurabilir ve görsel garipliklerden kazaya kadar.

Açıkça daha fazla oluşturmadığınız sürece, bir Windows Forms uygulamasında yalnızca bir UI iş parçacığı vardır. ,'u başka bir iş parçacığı oluşturabilir ve bir ileti döngüsü başlatabilirken, bunu yapmak için neden çok az neden vardır ve iki farklı UI iş parçacığı birbiriyle "konuşamaz", diğer herhangi bir iş parçacığı ile konuşabilir UI iş parçacığı.

+2

+1, bunu yapabildiğinizden bahsetmişken, ancak nadiren yapılması gerekenler ... –

+0

Peki ne zaman yeni bir Konu(). –

+0

@Griever: Bu yeni bir iş parçacığı başlatır, ancak kullanıcı arabiriminden tamamen ayrıdır. Yeni bir Thread başlangıcını her yerde başlatmak, yeni, alakasız bir iş parçacığı oluşturur. –

0

:

, Windows Forms ve WPF için benzer bir kavram aktif UYGULAMA başına bir UI iş parçacığı vardır.

ie: Uygulamayı başlattığınızda, bir iş parçacığı vardır, Application.Run (yeni Form1()) olduğunda bir UI iş parçacığı olur; denir.

Application.Run (yeni Form2()) yapmayı denerseniz; Çalışma zamanında "System.InvalidOperationException: Tek bir iş parçacığı üzerinde ikinci bir ileti döngüsünü başlatma geçerli bir işlem değil. Form.ShowDialog kullanın."

Aynı iş parçacığını paylaşmamak için iki ayrı forma gerçekten ihtiyacınız varsa, yeni bir iş parçacığı oluşturmanız, ardından Application.Run (yeni MyForm()) vb. Öğesini çağırmanız gerekir. Bu yaygın değildir.

+1

Bu doğru değil. Windows Forms'taki farklı formlar, ** aynı ** parçayı kullanır. Mesaj pompası, tüm bunları yanıtlıyor. –

+0

Tersine döndürdüm, kalıcı iletişim kutusu yeni bir iş parçacığı gerektiriyor, modelleme iletişim kutuları * yeni bir iş parçacığı gerektirmiyor *. Bu nokta, normal formların yeni bir form başlatıldığında, normal ipliklerin kullanıcılara dönüşebileceği anlamına gelmektedir. – David

+0

Bu hala doğru değil. Yeni bir iş parçacığından, bir ileti döngüsünü başlatmak için özel bir dikkat göstermeden "bir formun başlatılması", varsayılan olarak STA eksikliğinden dolayı (çoğu durumda) çökme de dahil olmak üzere her türlü soruna neden olacaktır. –

7

Bir UI iş parçacığı özel kılan özelliklerin bir numarası vardır:

  • , Windows iplik ile ilişkili bir mesaj kuyruğu vardır. Bu iş parçacığı üzerinde ilk pencere oluşturulduğu anda olur.
  • İş parçacığı, Windows'un pencerelere mesaj göndermesini sağlayan bir ileti döngüsü çalıştırır. Application.Run() öğesini çağırdığınızda ileti döngüsü oluşturulur.
  • İş parçacığı üzerinde COM başlatıldı ve tek iş parçacıklı bir daire istendi. Birçok Windows özelliklerinin düzgün çalışabilmesi için STA'ya ihtiyaç vardır; bu özellikler, tasarım gereği iş parçacığı için güvenli değildir. COM, bu özelliklerin her zaman bir iş parçacığı güvenli bir şekilde çağrılmasını sağlar, böylece bir iş parçacığından gelen çağrıyı STA iş parçacığına gerektiği şekilde sıralar. Bu özelliklerin örnekleri, Sürükle + Bırak, pano, kabuk iletişim kutuları (OpenFileDialog vb.), WebBrowser gibi ActiveX denetimleri, SetWindowsHookEx tarafından ayarlanan pencere kancaları, bir ekran okuyucu, UI otomasyon sağlayıcıları tarafından kullanılan erişilebilirlik sağlayıcılarıdır. Tüm harici kodlar, hiçbiri dişli olarak güvenli değil.
  • İş parçacığı hiçbir zaman herhangi bir işlemi engeller, yanıt verir ve kullanıcı arabirimi yanıt veren ve COM sıralama isteklerinin akmasını sağlamak için Windows iletilerini gerektiği gibi gönderebilir. Örneğin WaitHandle.WaitAny() 'ye çağrı yapmak açıkça yasaklanmış ve bir istisna oluşturmuştur. CLR'nin, deadlock'u önlemek için dahili bir mesaj döngüsünü pompalayarak WaitOne() ve lock için özel desteği vardır.

Bir işlemin başlangıç ​​iş parçacığı neredeyse her zaman UI iş parçacığı olarak seçilir, ancak bu zor bir gereklilik değildir. STA durumu, Main() yöntemindeki [STAThread] özniteliği tarafından seçilir.

Yukarıdaki gereksinimlerin karşılandığından emin olarak bir UI iş parçacığı oluşturabilirsiniz. Yani bir Win app aşağıdaki gibi görünebilir: kendi UI iş parçacığı üzerinde çalışan ikinci bir pencere oluşturur

var ui = new Thread(() => { Application.Run(new Form2()); }); 
    ui.SetApartmentState(ApartmentState.STA); 
    ui.Start(); 

. Bu düzenlemede sahip olduğunuz tipik bir sorun, artık iki ayrı pencereye sahip olmanız, birbirleriyle hiçbir şekilde ilişkilendirilmemenizdir. 2. pencere 1.e ait olamaz, 1'den bağımsız olarak kendi Z sırasına sahiptir. Kullanıcı tarafından ele almak zor. SystemEvents.UserPreferenceChanged olayı dikkat çekicidir, kaçınılmaz olarak olayını yanlış iş parçacığına dayatır ve bu da kilitlenmeye neden olur. WinForms kontrollerinin birçoğu onu abone olur. Nadir durumlarda, bir sıçrama ekranı gibi, bu kullanıcı arayüzünü hiç iyileştirmez.

+0

Detaylı cevabınızı beğendim. –

İlgili konular