Accessing WinForm UI from Rhino Service Bus consumer

126 views Asked by At

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.
1

There are 1 answers

2
Daniel Peñalba On

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