GVKun编程网logo

c# – Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?

10

关于c#–Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?的问题就给大家分享到这里,感谢你花时间阅读本站内容,

关于c# – Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于asp.net-mvc – ControllerActionInvoker、c# – WinForms中的WPF:虽然UI线程处于活动状态,但在Dispatcher.Invoke上被阻止、c# – 为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?、c# – 从control.Invoke返回值((MethodInvoker)委托{/ * … * /};我需要一些解释等相关知识的信息别忘了在本站进行查找喔。

本文目录一览:

c# – Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?

c# – Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?

我正在使用 WPF,我对执行顺序Control.dispatcher.BeginInvoke()和Control.dispatcher.Invoke()感到困惑.

我将在下面展示一个代码示例

backgroundThread = new Thread(BackgroundThread);
backgroundThread.Start();
public void BackgroundThread()
{
    this.dispatcher.BeginInvoke(new Action(delegate()
    {
      WriteLog("Run command 1");
    }));

    this.dispatcher.Invoke(new Action(delegate()
    {
      WriteLog("Run command 2");
    }));
}

我希望“命令1”将在“命令2”之前运行并完成,但有时似乎“命令2”在“命令1”之前运行.我对互联网和MSDN文档进行了很多研究,但我不明白为什么会这样.

有人请告诉我这些功能的规则究竟是什么?

非常感谢!

T& T公司

解决方法

在Invoke同步调用该操作时,BeginInvoke在与dispatcher关联的线程上异步调用您传递给它的Action.

换句话说,Invoke会立即执行您传递给它的Action,而BeginInvoke会将您传递给它的操作放在dispatcher队列中,这就像dispatcher将要执行的操作列表一样,但不能保证何时进行发生或一旦调度员完成其他事情等待该队列.

因此,有时dispatcher可能正在忙于执行其他操作并将您传递给BeginInvoke的操作放在队列的末尾,直到它可以执行它,然后它会立即执行您传递给Invoke的任何操作,这就是订单差异的原因.

asp.net-mvc – ControllerActionInvoker

asp.net-mvc – ControllerActionInvoker

ControllerActionInvoker类的用途是什么?

解决方法

基本上它是一个Controller类的扩展点,可以让您进入并影响控制器如何与参数,过滤器和Action本身进行交互.当请求已经路由到控制器时,控制器要求ControllerActionInvoker处理请求(通常涉及到在Controller上调用方法).

到目前为止,我已经看到的主要用法是向Action Filters提供依赖注入,如图所示,但是我确信我们将来会看到更多的用途.

c# – WinForms中的WPF:虽然UI线程处于活动状态,但在Dispatcher.Invoke上被阻止

c# – WinForms中的WPF:虽然UI线程处于活动状态,但在Dispatcher.Invoke上被阻止

我们在WinForms控件中嵌入了一个 WPF控件,该控件又作为ActiveX控件公开.此ActiveX最终用于由第三方开发的C应用程序.

在某些时候,ActiveX控件的UI变得冻结,而C应用程序的其余部分运行正常.经过一些调试后,我注意到每次调用Application.Current.dispatcher.Invoke时都阻止了WPF控件.但是,WinForms控件处理它的Control.Invoke调用就好了.每当我暂停调试器时,我都可以看到UI线程在C应用程序中做了一些工作,但似乎没有阻塞或等待任何事情.这就好像UI线程突然并且莫名其妙地拒绝执行WPF委托.

当C应用程序在很长一段时间(几分钟)内独占UI线程时,WPF控件有时会进入此状态.我要做的第一件事就是使用不同的线程进行这样一个耗时的任务,但正如我已经说过的,我不负责C应用程序正在做什么.无论如何,这不是我的WPF控件以这种方式运行的原因.我不知道如何解决这个问题;任何帮助,将不胜感激.

解决方法

我建议运行MS Debug Diagnostics Tool – http://support.microsoft.com/kb/2580960.

我们已经有了很好的结果来识别COM互操作阻塞问题,在我们的例子中,这是一个挂起的COM终结器阻塞垃圾收集.您可以在各种模式下运行它,但是当使用.NET分析运行时,它将突出显示终结器队列等的任何问题.运行起来有点笨拙,但它给你的信息是黄金.

c# – 为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?

c# – 为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?

考虑一下代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender,RoutedEventArgs e)
        {
            //System.Threading.Thread.CurrentThread = button.dispatcher.Thread
            button.dispatcher.Invoke(() => button.Content = "1234");
        }
    }

当然,button_Click在主线程上运行.

我的理解是button.dispatcher.Thread是主线程,只有当线程没有被阻塞时才会处理Invoke().但是,在这种情况下,主线程是否被阻止?即主线程正在等待dispatcher.Invoke()调用完成,dispatcher.Invoke()正在等待主线程释放.所以我希望在这里遇到僵局,但它不会陷入僵局.

为什么?

P.S:我知道在这种情况下我不需要dispatcher.Invoke,我可以直接调用button.Content =“1234”.我试图理解为什么在这种情况下不会发生死锁.

解决方法

我相信你的误解可能基于以下思维过程:

“好吧,Invoke会阻塞调用线程,直到操作完成.如果线程被阻塞,它如何在线程上执行操作?”

如果我们查看源代码,我们会看到回调不仅在同一个线程上调用,而且直接在Invoke方法内调用.主线程没有被阻止.

如果查看调度程序的Reference Source页面,您可以在Invoke方法的实现中看到if语句上面的以下注释,并在其中调用回调:

// Fast-Path: if on the same thread,and invoking at Send priority,// and the cancellation token is not already canceled,then just
// call the callback directly.
if(!cancellationToken.IsCancellationRequested && priority == dispatcherPriority.Send && CheckAccess())
{
    /* snipped */

    callback();

    /* snipped */
}

您在主线程上调用dispatcher.Invoke,该方法只需立即调用它即可处理.

*嗯,不是直接的,但Invoke(Action)的整个主体只是对上面代码所在方法的调用.

c# – 从control.Invoke返回值((MethodInvoker)委托{/ * … * /};我需要一些解释

c# – 从control.Invoke返回值((MethodInvoker)委托{/ * … * /};我需要一些解释

#1和#2之间有什么区别:

代码1(编译好):

byte[] GetSomeBytes()
  {
            return (byte[])this.Invoke((MethodInvoker)delegate 
            { 
                GetBytes(); 
            });
  }

  byte[] GetBytes()
  {
   GetBytesForm gbf = new GetBytesForm();

   if(gbf.ShowDialog() == DialogResult.OK)
   {
    return gbf.Bytes;
   }
   else
    return null;
  }

代码2(没有成功)

int GetCount()
{
       return (int)this.Invoke((MethodInvoker)delegate
       {
           return 3;            
       });
}

代码#2给了我,因为’System.Windows.Forms.MethodInvoker’返回void,返回关键字后面不能跟一个对象表达式.

我该如何解决?为什么(做)编译器认为代码#1是对的?

解决方法

要回答您的第一个问题,请尝试更改您的第一个示例,如下所示:

return (byte[])this.Invoke((MethodInvoker)delegate 
{ 
    return GetBytes(); 
});

此时,您将遇到相同的编译错误.

公共对象Invoke(Delegate方法)返回一个对象,因此您可以将返回值强制转换为任何对象并进行编译.但是,您传入一个MethodInvoker类型的委托,它具有签名委托void MethodInvoker().因此,在您转换为MethodInvoker的方法体内,您无法返回任何内容.

试试这个而不是第二个:

return (int)this.Invoke((Func<int>)delegate
{
    return 3;
});

FUNC< INT>是一个返回int的委托,因此它将被编译.

我们今天的关于c# – Control.Dispatcher.BeginInvoke()和Control.Dispatcher.Invoke()订单执行令人困惑?的分享就到这里,谢谢您的阅读,如果想了解更多关于asp.net-mvc – ControllerActionInvoker、c# – WinForms中的WPF:虽然UI线程处于活动状态,但在Dispatcher.Invoke上被阻止、c# – 为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?、c# – 从control.Invoke返回值((MethodInvoker)委托{/ * … * /};我需要一些解释的相关信息,可以在本站进行搜索。

本文标签: