this.InvokeRequired是假的,但是这个.Invoke挂起了UI

时间:2017-10-09 14:50:09

标签: c# multithreading winforms

我有winforms的情况,在datetimeControl.Leave方法中有一个验证结果是messagebox。用户选择无效日期,然后单击其他选项卡。现在Leave事件正在执行,消息框正在新选项卡中显示。单击“确定”后,UI将挂起。

我不允许将验证移到DateTimeControl.ValueChanged事件。

当我使用BeginInvoke时,我没有得到任何挂断。

this.BeginInvoke((Action)(() =>
                        _serviceProvider.GetService<IShell>().ShowMessageBox(Properties.Resources.NoAvailableReceiptsTitle,
                        string.Format(Properties.Resources.NoAvailableReceiptsMsgWithDepositDate,
                        _document.GroupDeposit.UserPostedOn.ToShortDateString(),
                        ((ITrustAccountInfo)_trustAccountCombo.Value).Code),
                        null,
                        MessageBoxIcon.Information,
                        MessageBoxButtons.OK)
                        ));

但是我们的应用程序非常庞大且非常复杂,我被要求使用InvokeRequired和Invoke。但InvokeRequired始终为false,并始终创建句柄。

if (this.IsHandleCreated)
{
    if (!this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(() =>
            _serviceProvider.GetService<IShell>().ShowMessageBox(Properties.Resources.NoAvailableReceiptsTitle,
            string.Format(Properties.Resources.NoAvailableReceiptsMsgWithDepositDate,
            _document.GroupDeposit.UserPostedOn.ToShortDateString(),
            ((ITrustAccountInfo)_trustAccountCombo.Value).Code),
            null,
            MessageBoxIcon.Information,
            MessageBoxButtons.OK)
            ));
    }
}

我试图检查控件是否已暂停。但这是错误的。 我检查了所有相关的帖子。

Invoke or BeginInvoke cannot be called on a control until the window handle has been created

Control.Invoke is hanging

我很困惑,BeginInvoke不会导致挂断,但Invoke会这样做。 今天是关于这个问题的第4天,我是这里的新员工。我会很感激任何提示。谢谢。

1 个答案:

答案 0 :(得分:-2)

我发现令人费解的是,你的函数的执行依赖于this.InvokeRequired。也就是说,如果不需要调用,则消息框似乎无关紧要。

我建议这样的事情:

public void InvokeIfNeeded(Action action)
{
  if (this.InvokeRequired)
    Invoke(action);
  else
    action(); // direct call   
}

换句话说:如果(并且仅当)需要Invoke,则通过Invoke()调用Action,否则直接调用它。