0

I have a WinForm screen that is also a message consumer (using Rhino ESB). If I try to update anything on the screen when I receive a message, nothing happens. A call to Invoke gives me an error that the handle is not created. The form is definitely created though, I'm firing a message on button click on the form and the background process sends a message back. It's with this return message I want to update the UI.

THIS IS NOT A DUPLICATE QUESTION, NONE OF THE SUGGESTED SOLUTIONS WORK.

I believe the difference here may be because I'm using Rhino Service bus. Rhino may be constructing a separate instance of my form rather than the one I'm using. I think what I probably need to do is to have Rhino use my instance of the form as the consumer by passing my instance into the IoC container Rhino is using. Another alternative is to move the Consumer off to it's own class and inject my Form into the consumer, and put a public method on my Form for the Consumer to use. This may work fine with my app because this is the main form and will never be disposed unless the app is closed. This would become problematic on another form that may be instantiated multiple times. Perhaps I could have my form "observe" another static object that a separate Consumer class updates. Please give suggestions as to the best approach.

public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
    public void Consume(MoveJobCompletedEvent message)
    {
        // This does nothing!
        txtLogs.Text = "\nJob completed!";
    }
}

This throws an error:

        this.BeginInvoke((MethodInvoker)delegate
        {
            txtLogs.Text += "\nJob job completed!";
        });
ERROR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
Ryan Langton
  • 6,294
  • 15
  • 53
  • 103
  • I've read these other articles, none of them work. Something is different here. – Ryan Langton Jan 17 '14 at 19:31
  • Post a reproduction with solution provided in that answer, which doesn't work. that sould solve your problem. – Sriram Sakthivel Jan 17 '14 at 19:55
  • I believe the difference is the usage of RSB. I think it may be making a separate instance of my form and that would explain why it's not fully initializing. Editing the question. – Ryan Langton Jan 18 '14 at 12:19

1 Answers1

0

It seems that you're consuming a JobCompleted event before the window handle is created. You could try the following:

public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
    public void Consume(MoveJobCompletedEvent message)
    {
        if (!this.HandleCreated)
            return;

        this.BeginInvoke((MethodInvoker)delegate
        {
            txtLogs.Text += "\nJob job completed!";
        });
    }
}
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219
  • If I do this it always returns. Why would the handle not be created when I can update the element from elsewhere on the form (just not within the consume method)? – Ryan Langton Jan 17 '14 at 16:48
  • The handle should be created some milliseconds after the window is created. So this is the way you can protect to call `BeginInvoke` if the handle has not been created yet. Other possibility is calling Control.CreateControl() after you create the `new MainForm()` – Daniel Peñalba Jan 17 '14 at 17:01