tags:

views:

80

answers:

2

The following method is launched from the constructor of UserControl. A cross thread exception is thrown, but I can't tell why:

 public override void Populate()
 {
  base.Populate ();
  LoadEditableList(IEditableList);

  ThreadStart fix = null;
  fix = delegate()
  {
   if (InvokeRequired)
   {
    Invoke(fix);
   }
   else
   {
    buttonAdd_Click(null, null);
   }
  };
  var thread = new Thread(fix);
  thread.Start();
 }

The buttonAdd_Click method adds an item to a ListView. Strangely, I avoid this error if I add a breakpoint to the if (InvokeRequired) line. This is very similar to a pattern I have written dozens of times, I suspect I am missing something due to new baby no sleep syndrome.

+2  A: 

I believe InvokeRequired doesn't return appropriate values until the windows handle has been constructed. Whereabouts in your constructor is this being called?

Just for a test, if you call Control.Handle first, like this:

IntPtr handle = Handle;

at the top of your Populate method, does that help? I'm not suggesting that as a permanent fix, but it would be inkeeping with it working if you break into the debugger - it'll be accessing the Handle property to display it, and that will force the handle to be created...

What thread is this constructor running on, compared with the thread responsible for its parent window? All the controls in a particular window should use the same UI thread.

Jon Skeet
I think you are correct. I fixed the issue, by tying the populate method to the VisibleChanged event. Thanks.
Jake Pearson
+1  A: 

You might be running into a known problem, see here, here and here for more info.

Matt Warren