1

请参阅MSDN上的线程安全调用教程,看看以下语句:

// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired) { 
    SetTextCallback d = new SetTextCallback(SetText);
    this.Invoke(d, new object[] { text });
} else {
    this.textBox1.Text = text;
}

当然,我在我的代码中已经多次使用它,并且理解了一点为什么要使用它。但是我仍然对这些陈述有一些不清楚的问题,所以请任何人帮助我找出它们。

问题是:

  1. 仅使用 if 正文中的语句,代码是否可以正确运行?我试过了,如果控件没有完全初始化,它似乎只是导致问题。不知道还有没有问题?
  2. 通过调用程序直接调用方法(else body)实例有哪些优势?它是否节省资源(CPU,RAM)或其他东西?

谢谢!

4

2 回答 2

2

当然,您总是可以使用 Invoker 进行调用,但是:

  • 它通常会使代码更冗长且难以阅读。
  • 它的效率较低,因为需要处理几个额外的层(设置委托、调用调度程序等)。

如果您确定您将始终在 GUI 线程上,您可以忽略上述检查并直接调用。

于 2012-05-21T03:29:25.243 回答
1
  1. 如果你总是只运行语句的第一部分if,它总是没问题的,因为Invoke已经检查你是否在 UI 线程上。
    1. 您不想这样做的原因是Invoke,即使您已经在正确的线程上,也必须做很多工作才能运行您的方法。下面是它要做的(摘自 Control.cs 的源代码):
      • 通过父控制链的向上遍历找到编组控制
      • 检查控件是否为 ActiveX 控件,如果是,则要求非托管代码权限
      • 确定是否需要异步调用调用以避免潜在的死锁
      • 获取调用线程的执行上下文的副本,以便在最终调用委托时使用相同的安全权限
      • 将方法调用排入队列,然后发布一条消息以调用该方法,然后等待(如果是同步的)直到它完成

在从 UI 线程直接调用期间,不需要第二个分支中的任何步骤,因为所有先决条件都已经得到保证,所以它肯定会更快,尽管公平地说,除非你非常频繁地更新控件,你'不太可能注意到任何差异。

于 2012-05-28T05:10:36.027 回答