0

I have a situation in winforms, there is a validation in datetimeControl.Leave method which results in messagebox. User selects a invalid date and then clicks on a different tab. now the Leave event is executing and messagebox is being displayed in a new tab. After clicking OK, UI hangs up.

I am not allowed to move validation to DateTimeControl.ValueChanged event.

When i used BeginInvoke, i don't get any hangups.

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)
                        ));

however our application is very huge and very complex and i was asked to use InvokeRequired and Invoke. But InvokeRequired is always false and handle is always created.

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)
            ));
    }
}

i tried to check if the control isDisposed. but that is false. I checked all the related posts.

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

Control.Invoke is hanging

I am puzzled that BeginInvoke doesn't result in hangup but Invoke does. Today is my Day4 on this problem and i am a new hire here. I would appreciate any hints. Thank you.

lama
  • 65
  • 1
  • 11
  • When you say the message box hangs up the UI - but thats what its supposed to do - it stops everything till you respond.. please explain more how this was not supposed to be the case – BugFinder Oct 09 '17 at 15:02
  • BeginInvoke() is very useful to solve re-entrancy problems. Such as the ones you get when you jerk the focus away in a focusing event. It ensures that the troublesome code runs *after* the event handling is complete. But you completely ruin that by using Invoke(), now you got the re-entrancy problem back. Since it doesn't delay running the risky code. So whomever told you to use Invoke, and especially InvokeRequired, completely misunderstands what problem you are trying to solve. You must ignore him. – Hans Passant Oct 09 '17 at 15:04
  • Do get ahead without this awful way to slap the user across the face. ErrorProvider is useful and doesn't cause these kind of problems. – Hans Passant Oct 09 '17 at 15:06
  • Thank you Hans. We use ErrorProvider in different part of the code. For some reason they stuck with MessageBoxes in this module. I was not familiar with ErrorProvider in winforms before. But thanks for pointing me there. – lama Oct 09 '17 at 15:21

1 Answers1

-2

I find it puzzling, that the execution of your function depends on this.InvokeRequired. That is, the messagebox seems irrelevant, if no invoke is required.

I'd recommend something like this:

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

In other words: If (and only if) an Invoke is required, the Action is called via Invoke(), otherwise call it directly.

DasKrümelmonster
  • 5,816
  • 1
  • 24
  • 45