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

  • Question

  • My vb.net form utilizes a C# UserControl to display real time asynch socket data which I can see using a packetsniffer that is is being returned correctly.
    The UserControl is throws this error when it attempts to display the data from the background thread to the RichTextBox Control being utilized to display the data.
    Here is the vb.net code which sets the System Timer Properties and kick starts the asynchronous process.
    I just need how to solve this error so that the Rich Text Control of the C# UserControl appends the returned text and displays it on the VB.Net form that contains it.
    Thank you!

    Public Sub FetchFromDeviceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FetchFromDeviceToolStripMenuItem.Click
    
         Dim ctrl As New AsynchConnectSendReceive.FormDisplayRealTimeAlarmHistory
    
         ctrl.TimerNetwork.Interval = 2000
         ctrl.TimerNetwork.Enabled = True
         ctrl.BeginConnect("10.0.110.35", 50000)
         ctrl.TimerNetwork.Start()
    
    End Sub
    namespace AsynchConnectSendReceive
    {
       partial class FormDisplayRealTimeAlarmHistory
    
       private void InitializeComponent()
       {
          this.richTextBoxPrintCtrl1 = new RichTextBoxPrintCtrl.RichTextBoxPrintCtrl();
          public RichTextBoxPrintCtrl.RichTextBoxPrintCtrl richTextBoxPrintCtrl1;
       }
    }
    
    namespace AsynchConnectSendReceive
    {
       public partial class FormDisplayRealTimeData : UserControl
       {
           public System.Timers.Timer TimerNetwork;
           public FormDisplayRealTimeData()
           {
                InitializeComponent();
                TimerNetwork = new System.Timers.Timer();
                TimerNetwork.Elapsed += new ElapsedEventHandler(OnTimedEvent);
           }
           public void OnTimedEvent(object source, ElapsedEventArgs e)
           {
              Send(state.workSocket, ByteArrayMessageForDevice);
            }
    
           public void BeginConnect(string host, int port)
           {
              Socket s = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream,
                                    ProtocolType.Tcp);
              s.BeginConnect(host, port, new AsyncCallback(ConnectCallback), s);
           }
    
           private void Send(Socket client, byte[] sendByteArrayMessageToDevice)
           {
                    client.BeginSend(sendByteArrayMessageToDevice,
                     0,
                     sendByteArrayMessageToDevice.Length,
                     SocketFlags.None,
                     new AsyncCallback(SendCallback),
                     client);
           }
        }
    }
    Wednesday, February 17, 2010 4:53 PM

Answers

  • The error message occurs because you're starting your timer in the user control before you're displaying the form.

    Control.Invoke works by using the message pump, and passing a message to the control to process the delegate.  This only works once the control's handle (Control.Handle) has been created, which happens when the form/control is loaded, not when it's constructed.

    It sounds like you're constructing your UserControl,and starting your connect timer immediately.  You need to not start the timers until the control is displayed - that will prevent this error from occurring.

    Alternatively, you can leave your method as-is, but skip the text box line if UserControl.IsHandleCreated is false.  This property will return false until the UserControl has been loaded - until it returns true, Control.Invoke will fail.



    Reed Copsey, Jr. - http://reedcopsey.com
    • Proposed as answer by Kira Qian Thursday, February 18, 2010 7:58 AM
    • Marked as answer by Kira Qian Thursday, February 25, 2010 6:35 AM
    Wednesday, February 17, 2010 5:14 PM

All replies

  • The error message occurs because you're starting your timer in the user control before you're displaying the form.

    Control.Invoke works by using the message pump, and passing a message to the control to process the delegate.  This only works once the control's handle (Control.Handle) has been created, which happens when the form/control is loaded, not when it's constructed.

    It sounds like you're constructing your UserControl,and starting your connect timer immediately.  You need to not start the timers until the control is displayed - that will prevent this error from occurring.

    Alternatively, you can leave your method as-is, but skip the text box line if UserControl.IsHandleCreated is false.  This property will return false until the UserControl has been loaded - until it returns true, Control.Invoke will fail.



    Reed Copsey, Jr. - http://reedcopsey.com
    • Proposed as answer by Kira Qian Thursday, February 18, 2010 7:58 AM
    • Marked as answer by Kira Qian Thursday, February 25, 2010 6:35 AM
    Wednesday, February 17, 2010 5:14 PM
  • Also Control has a HandleCreated event which you can override if subclassing (OnHandleCreated) or subscribe to if you're an external consumer.
    Wednesday, February 17, 2010 7:39 PM
  • Hi hazz,

    I am writing to check the status of the issue on your side. Could you please let me know if the suggestion works for you? If you have any questions or concerns, please feel free to let me know. I will be more than happy to be of assistance.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
    Monday, February 22, 2010 9:06 AM