InvokeRequired doubt

2019-08-02 08:05发布

The following method will be invoked from a non UI thread. Should I check InvokeRequired, for calling these items in the method?

a. this._moduleStatusGrid.Invalidate()
b. this.Close()

private void CheckIfAllModulesInitComplete()
      {
        this._moduleStatusGrid.Invalidate();
        if (this._moduleDataList.Count(moduleData => !moduleData.IsInitOver) == 0)
        {
          this._footprint.DeActivate();
          this.Close();
        }
      }

2条回答
乱世女痞
2楼-- · 2019-08-02 08:30

Control.Invoke and Control.BeginInvoke are safe to call from the UI thread and non-UI threads, so if you already know you are on a non-UI thread there is no harm (IMO) skipping the check and just calling Invoke/BeginInvoke.

Example:

anyControl.Invoke((MethodInvoker)delegate{
    // anything to run on UI thread here
});
查看更多
祖国的老花朵
3楼-- · 2019-08-02 08:31

It sounds like you could be asking one of the following

  1. Given that this method runs in a background thread, within the methods Invalidate and Close should I be checking the InvokeRequired property?
  2. Given that this method runs in a background thread the InvokeRequired property will always return false so should I just avoid checking it?

For #1 the answer is no. The methods Close and Invalidate don't have a responsibility to check the InvokeRequired property. It is an implicit part of their contract that the InvokeRequired property be false before they are called.

For #2, yes if it's always called on a background thread I would skip the check and just go straight to the Invoke methods.

In either case I would rewrite the method as follows.

private void CheckIfAllModulesInitComplete()
{
  MethodInvoker del = delegate {
    this._moduleStatusGrid.Invalidate();
    if (this._moduleDataList.Count(moduleData => !moduleData.IsInitOver) == 0)
    {
      this._footprint.DeActivate();
      this.Close();
    }
  };
  this.Invoke(del, null);
}
查看更多
登录 后发表回答