Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在WPF应用程序中使用C#Dispatcher_C#_Wpf_Invoke_Dispatcher - Fatal编程技术网

在WPF应用程序中使用C#Dispatcher

在WPF应用程序中使用C#Dispatcher,c#,wpf,invoke,dispatcher,C#,Wpf,Invoke,Dispatcher,我正在构建一个聊天客户端,但对如何使用dispatcher没有100%的把握。所以问题是我有这样一种方法: public void LostConnection() { myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); } 我是否需要使用调度程序调用(myGUI.chatBox…中的语句?非常感谢您的帮助。像这样的事情(从我的头顶上)应该可以: p

我正在构建一个聊天客户端,但对如何使用
dispatcher
没有100%的把握。所以问题是我有这样一种方法:

public void LostConnection()
{
    myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n");
}
我是否需要使用
调度程序调用
(myGUI.chatBox…
中的语句?非常感谢您的帮助。

像这样的事情(从我的头顶上)应该可以:

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

您的应用程序有一个主UI线程(通常
ManagedThreadId==1
)。通常,在聊天应用程序中,您的事件将通过其他线程(专用套接字侦听线程或侦听代码中的线程池线程)传入。如果您想从在其他线程上获得pull的事件更新UI,则必须使用dispatcher。这里一个有用的测试是
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(  
调用vs开始调用
如果希望当前线程等待UI线程处理分派代码,请使用
Invoke
;如果希望当前线程继续而不等待UI线程上的操作完成,请使用
BeginInvoke

MessageBox、Dispatchers和Invoke/BeginInvoke:
Dispatcher.Invoke
将阻止您的线程,直到MessageBox被解除。
Dispatcher.BeginInvoke
将允许线程代码继续执行,同时UI线程将阻止MessageBox调用,直到其被解除

CurrentDispatcher与Current.Dispatcher
请注意
Dispatcher.CurrentDispatcher
,因为我的理解是,它将为当前线程而不是UI线程返回一个Dispatcher。通常,您对UI线程-
应用程序上的dispatcher感兴趣。Current.dispatcher
始终返回此值

附加说明:
如果您发现必须经常检查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));
});

我在
Application.Current.Dispatcher.BeginInvoke
object.Invoke()方法方面遇到问题

这对我很有用:

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
     // code...
}));

这取决于…该方法运行的线程是什么?另外,为了确定,您正在使用WPF,对吗?(
Dispatcher
仅适用于此。)您使用的UI框架是什么?(WinForms、WPF或SL)它们之间存在差异Yep,正如svick所建议的,这取决于您是否从另一个线程(异步)触摸您的UI。下面我为没有指定它是WPF应用程序和它是我的后端试图更新我的GUI而道歉,是的,这将是跨线程的。我想我已经成功了,所以感谢你们所有的帮助!!!嘿,伙计们,对不起,我没有指定,是的,它是一个wpf应用程序,是的,它是跨线程。我在后端设置委托,然后通知我的模型,然后模型将调用调度程序方法并更新gui界面。我仍然没有通过intellesense添加调度器的选项,但我会尝试强制它,看看它是否运行。谢谢大家!还有其他提示吗?如果您已经包括使用语句并使用Application.Current.Dispatcher,您应该会得到一个结果。如果你的“后端”在dll中,那么你需要将UI线程调度程序传递到你的对象中,这样它就可以引用它了。@Ricibob,我只是挑剔一点,我认为UI线程的Id不必总是为1。加上一个向上投票,因为你使用
指令编写
,这对很多C#初学者很有帮助。这将在WinForms中实现。这个问题显然是关于WPF的。这在问题上并不明显。这是几年前说过的话。重复的答案不应张贴。