Michael,
You cannot parent control created in different threads. This Windows OS
restriction. Further mode you cannot call methods and set properties of a
control from a different thread than the one created the control.
In remoting scenarious this could be kind of tricky because all
notifications that comes form the remote objects are executed in worker
threads from the thread pool. Use Control.Invoke to marshal them to the UI
thread.
Why do you need to start this new thread in order to create the controls?
I hope you know that the following code executes
this.CreateCommunicatorControls in a thread from the thread pool
> MethodInvoker invoker = new
> MethodInvoker(this.CreateCommunicatorControls);
> this.Invoke(invoker);

Signature
HTH
Stoitcho Goutsev (100) [C# MVP]
> Hi,
>
[quoted text clipped - 34 lines]
> Regards,
> Michael
Michael Groeger - 08 Dec 2005 15:16 GMT
Hi Stoitcho,
I know that I cannot parent control created in different threads. That's why
I am already invoking the main UI thread (see the EventHandler
EventProxy_Initialized). It's very strange what's going on there which I saw
after modifying the code a little:
--------- snip ---------
private void EventProxy_Initialized(object sender, EventArgs e)
{
CreateCommunicatorControls();
}
private void CreateCommunicatorControls()
{
System.Diagnostics.Trace.WriteLine("CreateCommunicatorControls called");
// check for invokation
if (this.InvokeRequired)
{
System.Diagnostics.Trace.WriteLine("Invoke was required");
MethodInvoker invoker = new
MethodInvoker(this.CreateCommunicatorControls);
this.Invoke(invoker);
}
else
System.Diagnostics.Trace.WriteLine("Invoke was not
required");
try
{
[...]
// create controls and add them to a panel on the form
this.panelCommunicator.Controls.Add(newCommCtrl);
[...]
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
}
}
--------- snip ---------
After executing the code the output was the following:
CreateCommunicatorControls called
Invoke was required
CreateCommunicatorControls called
Invoke was not required
Controls created on one thread cannot be parented to controls on a different
thread
I was somehow wondered and diagnosted that the panelCommunicator was running
on a different UI thread, because this.panelCommunicator.InvokeRequired
returned true. I still do not understand why because the panel gets created
in the forms constructor's InitializeComponent() method.
To answer your question Stoitcho:
I am getting a remote event via remoting. Since this event is not raised
from the UI thread I am required to create the controls from a different and
invoke the main UI thread from that one. Each event registers a control,
prior to the event I do not know how many controls I need, that's why the
controls get created dynamically.
Regards,
Michael
> Michael,
>
[quoted text clipped - 58 lines]
> > Regards,
> > Michael
Stoitcho Goutsev (100) [C# MVP] - 08 Dec 2005 16:00 GMT
Michael,
Sorry, I saw wrong. I though (saw) that you call Invoke on the invoker
object.
The problem is here:
After you check that the call requires Invoke you correctly invoke the
method in the UI thread. And the UI thread calls the methods recursively.
This time InvokeRequired is false and you continue with control creation
that by all rules succeeds.
The methods executed by the UI thread finishes and the worker thread
continues after the call *this.Invoke()*. At this point you should do
*return* to cancel execution for the rest of the code. You fail to do that
(no *return* statement) so the execution continues and goes through the code
of creating the control again this time in the worker thread. And here is
the moment where you get the exception.
You should change the code to look like
if (this.InvokeRequired)
{
System.Diagnostics.Trace.WriteLine("Invoke was required");
MethodInvoker invoker = new
MethodInvoker(this.CreateCommunicatorControls);
this.Invoke(invoker);
}
private void CreateCommunicatorControls()
{
System.Diagnostics.Trace.WriteLine("CreateCommunicatorControls called");
// check for invokation
if (this.InvokeRequired)
{
System.Diagnostics.Trace.WriteLine("Invoke was required");
MethodInvoker invoker = new
MethodInvoker(this.CreateCommunicatorControls);
this.Invoke(invoker);
return; //NOTE: PAY ATTENTION ON THIS *RETURN*
}
// YOU DON'T NEED THE ELSE CLAUSE SINCE THE EXECUTION WON'T COME HERE IF
INVOKE IS REQUIRED
System.Diagnostics.Trace.WriteLine("Invoke was not required");
try
{
[...]
// create controls and add them to a panel on the form
this.panelCommunicator.Controls.Add(newCommCtrl);
[...]
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
}
}

Signature
HTH
Stoitcho Goutsev (100) [C# MVP]
> Hi Stoitcho,
>
[quoted text clipped - 136 lines]
>> > Regards,
>> > Michael
Michael Groeger - 09 Dec 2005 09:31 GMT
Stoitcho,
oh sorry, I forgot this one. This of course could have been the reason why
...thanks!
Regards,
Michael
> Michael,
>
[quoted text clipped - 199 lines]
> >> > Regards,
> >> > Michael