アプリは、メインUIスレッド(通常はManagedThreadId==1
)を持っています。通常、チャットアプリケーションでは、イベントは他のスレッド(専用ソケットリスンスレッドまたはリスニングコードのスレッドプールスレッドのいずれか)に入ります。他のスレッドを取得するイベントからUIを更新する場合は、ディスパッチャを使用する必要があります。便利なテストは、Dispatcher.CheckAccess()
メソッドで、コードがUIスレッドの場合はtrueを返し、他のスレッドの場合はfalseを返します。あなたが使用することができ、メインウィンドウにいる場合
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));
}));
}
:典型的な呼び出しは次のようになります
Dispatcher.BeginInvoke(...
あなたが他の何らかの文脈にいる場合など、ビューモデル、次に使用:
Application.Current.Dispatcher.BeginInvoke(
BeginInvokeを対起動
使用Invoke
あなたは現在のスレッドがUIスレッドまで待つしたい場合UIスレッドで処理が完了するのを待たずに現在のスレッドを続行したい場合は、ディスパッチコードまたはBeginInvoke
を処理しました。
メッセージボックス、ディスパッチャと起動/ BeginInvokeを:メッセージボックスが却下されるまで
Dispatcher.Invoke
があなたのスレッドをブロックします。
Dispatcher.BeginInvoke
は、UIスレッドがMessageBox呼び出しでブロックされるまでスレッドコードが実行を継続できるようにします。
CurrentDispatcherとCurrent.Dispatcher!
Dispatcher.CurrentDispatcher
私の理解では、UIスレッドではなく、現在のスレッドのDispatcherが返されます。通常、UIスレッドのディスパッチャに興味がありますか?Application.Current.Dispatcher
は常にこれを返します。
追加注:
あなたは、多くの場合、ディスパッチャCHECKACCESSを確認するために行っている見つけている場合は、便利なヘルパーメソッドがある:として呼び出すことができ
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
:
DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
こと依存しています...どのスレッドがそのメソッドを実行しますか?また、WPFを使用していることを確認するだけです。 ( 'Dispatcher'はそれだけで動作します。) – svick
どのようなUIフレームワークを使用していますか?(WinForms、WPF、またはSL)それらの間に違いがある –
svickが示唆するように、別のスレッドからあなたのUIに触れているかどうかによって異なります(非同期的に) – gideon