Hi,

I have a form which acts as monitor for a service. The form and the monitor
communicate via remoting. Because it takes some time for the service to
startup some controls are added to the form when a certain event is raised
by the service.

However, when handling this event I do the following:

--------- snip ---------

private void EventProxy_Initialized(object sender, EventArgs e)
{
MethodInvoker invoker = new
MethodInvoker(this.CreateCommunicatorControls);
this.Invoke(invoker);
}

private void CreateCommunicatorControls()
{
// create controls and add them to a panel on the form
this.panelCommunicator.Controls.Add(newCommCtrl);
[...]
}

--------- snip ---------

The panel on the form is created from the main UI thread of the form., but I
still get the exception "Controls created on one thread cannot be parented
to controls on a different thread" when adding the new control to the panel.

Does anybody know what the problem is?

Regards,
Michael

Re: Problem creating controls from other thread w/ invoke by Stoitcho

Stoitcho
Thu Dec 08 08:45:54 CST 2005

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);


--
HTH
Stoitcho Goutsev (100) [C# MVP]

"Michael Groeger" <google.news@web.de> wrote in message
news:eC24jA%23%23FHA.1312@TK2MSFTNGP09.phx.gbl...
> Hi,
>
> I have a form which acts as monitor for a service. The form and the
> monitor
> communicate via remoting. Because it takes some time for the service to
> startup some controls are added to the form when a certain event is raised
> by the service.
>
> However, when handling this event I do the following:
>
> --------- snip ---------
>
> private void EventProxy_Initialized(object sender, EventArgs e)
> {
> MethodInvoker invoker = new
> MethodInvoker(this.CreateCommunicatorControls);
> this.Invoke(invoker);
> }
>
> private void CreateCommunicatorControls()
> {
> // create controls and add them to a panel on the form
> this.panelCommunicator.Controls.Add(newCommCtrl);
> [...]
> }
>
> --------- snip ---------
>
> The panel on the form is created from the main UI thread of the form., but
> I
> still get the exception "Controls created on one thread cannot be parented
> to controls on a different thread" when adding the new control to the
> panel.
>
> Does anybody know what the problem is?
>
> Regards,
> Michael
>
>



Re: Problem creating controls from other thread w/ invoke by Michael

Michael
Thu Dec 08 09:16:35 CST 2005

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



"Stoitcho Goutsev (100) [C# MVP]" <100@100.com> schrieb im Newsbeitrag
news:eAiycXA$FHA.3136@TK2MSFTNGP15.phx.gbl...
> 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);
>
>
> --
> HTH
> Stoitcho Goutsev (100) [C# MVP]
>
> "Michael Groeger" <google.news@web.de> wrote in message
> news:eC24jA%23%23FHA.1312@TK2MSFTNGP09.phx.gbl...
> > Hi,
> >
> > I have a form which acts as monitor for a service. The form and the
> > monitor
> > communicate via remoting. Because it takes some time for the service to
> > startup some controls are added to the form when a certain event is
raised
> > by the service.
> >
> > However, when handling this event I do the following:
> >
> > --------- snip ---------
> >
> > private void EventProxy_Initialized(object sender, EventArgs e)
> > {
> > MethodInvoker invoker = new
> > MethodInvoker(this.CreateCommunicatorControls);
> > this.Invoke(invoker);
> > }
> >
> > private void CreateCommunicatorControls()
> > {
> > // create controls and add them to a panel on the form
> > this.panelCommunicator.Controls.Add(newCommCtrl);
> > [...]
> > }
> >
> > --------- snip ---------
> >
> > The panel on the form is created from the main UI thread of the form.,
but
> > I
> > still get the exception "Controls created on one thread cannot be
parented
> > to controls on a different thread" when adding the new control to the
> > panel.
> >
> > Does anybody know what the problem is?
> >
> > Regards,
> > Michael
> >
> >
>
>



Re: Problem creating controls from other thread w/ invoke by Stoitcho

Stoitcho
Thu Dec 08 10:00:43 CST 2005

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


--
HTH
Stoitcho Goutsev (100) [C# MVP]

"Michael Groeger" <google.news@web.de> wrote in message
news:uFE2YpA$FHA.3340@TK2MSFTNGP12.phx.gbl...
> 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
>
>
>
> "Stoitcho Goutsev (100) [C# MVP]" <100@100.com> schrieb im Newsbeitrag
> news:eAiycXA$FHA.3136@TK2MSFTNGP15.phx.gbl...
>> 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);
>>
>>
>> --
>> HTH
>> Stoitcho Goutsev (100) [C# MVP]
>>
>> "Michael Groeger" <google.news@web.de> wrote in message
>> news:eC24jA%23%23FHA.1312@TK2MSFTNGP09.phx.gbl...
>> > Hi,
>> >
>> > I have a form which acts as monitor for a service. The form and the
>> > monitor
>> > communicate via remoting. Because it takes some time for the service to
>> > startup some controls are added to the form when a certain event is
> raised
>> > by the service.
>> >
>> > However, when handling this event I do the following:
>> >
>> > --------- snip ---------
>> >
>> > private void EventProxy_Initialized(object sender, EventArgs e)
>> > {
>> > MethodInvoker invoker = new
>> > MethodInvoker(this.CreateCommunicatorControls);
>> > this.Invoke(invoker);
>> > }
>> >
>> > private void CreateCommunicatorControls()
>> > {
>> > // create controls and add them to a panel on the form
>> > this.panelCommunicator.Controls.Add(newCommCtrl);
>> > [...]
>> > }
>> >
>> > --------- snip ---------
>> >
>> > The panel on the form is created from the main UI thread of the form.,
> but
>> > I
>> > still get the exception "Controls created on one thread cannot be
> parented
>> > to controls on a different thread" when adding the new control to the
>> > panel.
>> >
>> > Does anybody know what the problem is?
>> >
>> > Regards,
>> > Michael
>> >
>> >
>>
>>
>
>



Re: Problem creating controls from other thread w/ invoke by Michael

Michael
Fri Dec 09 03:31:45 CST 2005

Stoitcho,

oh sorry, I forgot this one. This of course could have been the reason why
...thanks!

Regards,
Michael

"Stoitcho Goutsev (100) [C# MVP]" <100@100.com> schrieb im Newsbeitrag
news:em6RQBB$FHA.3308@TK2MSFTNGP11.phx.gbl...
> 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);
> }
> }
>
>
> --
> HTH
> Stoitcho Goutsev (100) [C# MVP]
>
> "Michael Groeger" <google.news@web.de> wrote in message
> news:uFE2YpA$FHA.3340@TK2MSFTNGP12.phx.gbl...
> > 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
> >
> >
> >
> > "Stoitcho Goutsev (100) [C# MVP]" <100@100.com> schrieb im Newsbeitrag
> > news:eAiycXA$FHA.3136@TK2MSFTNGP15.phx.gbl...
> >> 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);
> >>
> >>
> >> --
> >> HTH
> >> Stoitcho Goutsev (100) [C# MVP]
> >>
> >> "Michael Groeger" <google.news@web.de> wrote in message
> >> news:eC24jA%23%23FHA.1312@TK2MSFTNGP09.phx.gbl...
> >> > Hi,
> >> >
> >> > I have a form which acts as monitor for a service. The form and the
> >> > monitor
> >> > communicate via remoting. Because it takes some time for the service
to
> >> > startup some controls are added to the form when a certain event is
> > raised
> >> > by the service.
> >> >
> >> > However, when handling this event I do the following:
> >> >
> >> > --------- snip ---------
> >> >
> >> > private void EventProxy_Initialized(object sender, EventArgs e)
> >> > {
> >> > MethodInvoker invoker = new
> >> > MethodInvoker(this.CreateCommunicatorControls);
> >> > this.Invoke(invoker);
> >> > }
> >> >
> >> > private void CreateCommunicatorControls()
> >> > {
> >> > // create controls and add them to a panel on the form
> >> > this.panelCommunicator.Controls.Add(newCommCtrl);
> >> > [...]
> >> > }
> >> >
> >> > --------- snip ---------
> >> >
> >> > The panel on the form is created from the main UI thread of the
form.,
> > but
> >> > I
> >> > still get the exception "Controls created on one thread cannot be
> > parented
> >> > to controls on a different thread" when adding the new control to the
> >> > panel.
> >> >
> >> > Does anybody know what the problem is?
> >> >
> >> > Regards,
> >> > Michael
> >> >
> >> >
> >>
> >>
> >
> >
>
>