2011-10-20 18 views
16

Bir sohbet istemcisi yapıyorum ve dispatcher'u nasıl kullanacağım konusunda% 100 emin değilim.C# Dispatcher'ı kullanma

public void LostConnection() 
{ 
    myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); 
} 

i Dispatcher.Invoke ile (myGUI.chatBox...) içinde ifadeyi surrond gerekir mi: Yani soru Ben gibi bir yöntem var mı? Herhangi bir yardım için minnettarım. (Başımın üstü kapalı) böyle

+0

O bağlıdır ... Bu hangi iş parçacığı üzerinde çalışır? Ayrıca, emin olmak için WPF kullanıyorsunuz değil mi? ('Dispatcher 'sadece bununla çalışır.) – svick

+1

Hangi kullanıcı arabirimi çerçevesini kullanıyorsunuz?(WinForms, WPF veya SL) Aralarında –

+0

Yep var, svick önerileri gibi, başka bir iş parçacığından (eşzamansız olarak) UI'nize dokunduğunuza göre değişir. – gideon

cevap

68

uygulama, bir ana UI iş parçacığı (genellikle ManagedThreadId==1) sahiptir. Tipik olarak bir sohbet uygulamasında, etkinlikleriniz diğer konulara (dinleme soketinden özel soket dinleme konuları veya iplik havuzu ipleri) gelir. Kullanıcı Arabirimini, başka bir iş parçacığı üzerinde çekilen bir olaydan güncellemek istiyorsanız, dağıtıcıyı kullanmalısınız. Burada yararlı bir test, kod UI iş parçacığında doğruysa ve diğer bazı iş parçacıklarında ise true olarak geri dönen Dispatcher.CheckAccess() yöntemidir. Eğer ana pencerede iseniz

using System.Windows.Threading; // For Dispatcher. 

if (Application.Current.Dispatcher.CheckAccess()) { 
    network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
} 
else { 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{ 
     network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
    })); 
} 

kullanabilirsiniz:

Dispatcher.BeginInvoke(... 

Eğer someother bağlamda iseniz bir görünüm modeli örneğin ardından kullanın: Tipik bir çağrı şey gibi görünüyor

Application.Current.Dispatcher.BeginInvoke( 

istediğiniz çağır'ı BeginInvoke vs
Kullanım Invoke akım iplik beklemek UI iş parçacığı kadar Geçerli iş parçacığının, UI iş parçacığı üzerinde işlemin tamamlanmasını beklemeden devam etmesini istiyorsanız, gönderme kodunu veya BeginInvoke'u işledi.

MessageBox, Görevlendiriciler ve Çağırma/Beginınvoke: MessageBox görevden kadar
Dispatcher.Invoke senin iplik engeller.
Dispatcher.BeginInvoke, UI iş parçacığı işten atılana kadar MessageBox çağrısında engel olurken iş parçacığınızın yürütülmeye devam etmesine izin verir.

CurrentDispatcher vs Current.Dispatcher!
Dispatcher.CurrentDispatcher numaralı ürüne sahip olun, bunun anlamı, iş parçacığı için UI iş parçacığı için bir Dispatcher döndürecektir. Genel olarak UI iş parçacığı üzerindeki dağıtıcıyla ilgileniyorsunuz - Application.Current.Dispatcher her zaman bunu döndürür.

Ek not:
Eğer CheckAccess sıklıkla sonra faydalı bir yardımcı yöntemdir memuru kontrol etmek zorunda olan bulgu varsa:

public void DispatchIfNecessary(Action action) { 
    if (!Dispatcher.CheckAccess()) 
     Dispatcher.Invoke(action); 
    else 
     action.Invoke(); 
} 

çağrılabilir hangi gibidir:

DispatchIfNecessary(() => { 
    network_links.Add(new NetworkLinkVM(link, start_node, end_node)); 
}); 
+0

Hey çocuklar, üzgünüm, ben belirtmedim, evet bir wpf uygulaması ve evet çapraz iş parçacığı. Ardından, arka taraftaki delegeyi ayarlıyorum, ardından modelimi uyarır ve daha sonra bu dağıtıcı yöntemini çağırır ve gui arayüzünü günceller. Ben hala bir dağıtıcı eklemek için intellesense ile bir seçenek alamıyorum ama zorlamak ve çalışıp çalışmadığını görmek için çalışacağım. Teşekkürler beyler! Başka ipuçları var mı? – Tombo890

+0

Eğer ifadeyi kullanarak eklediyseniz ve Application.Current.Dispatcher'ı kullanırsanız, sonuç almalısınız. Eğer "arka uç" kelimeniz bir dll ise, o zaman UI iş parçacığı ileticisini nesnenize oraya yönlendirmeniz gerekir. – Ricibob

+0

@Ricibob, sadece nitpicky olmak için, UI iş parçacığının her zaman Kimlik 1'e sahip olmadığını düşünüyorum. – svick

2

şey çalışmalıdır:

public void LostConnection() 
{ 
    myGUI.Invoke 
     ((MethodInvoker)delegate 
    { 
     myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); 
    }); 
} 
+0

Bu, WinForms'ta olurdu. Bu soru WPF ile ilgili. – svick

+1

Evet. Bu sorudan belli değildi. –

İlgili konular