Problem creating controls with multi-threading

L

Ludovic SOEUR

Have everyone tried to create controls in separated threads ? I have a
problem that I do not understand.
To simplify the explanations, I wrote theses few lines to show an example of
the problem.
This program do nothing more than showing a button "Start thread". When it
is pushed, a new thread is started in which a usercontrol is created,
showing another button. That's all.
Everything works, but, when like this source code I put the line (line 23)
userControl1.UselessFunction();
it fails (lock for a very very long time) and I have to kill the task.
This useless function only shows the button ! That 's strange, isn't it ?

I tried to move the line after the line 24
Invoke(new AddControl_Delegate(AddControl),new object[1] {userControl1});
and in this case, it works perfectly !

Could someone help me please ?

Thanks,
Ludovic SOEUR.

Here is the source code :

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

public class Form1 : Form {
[STAThread]
static void Main() {
Application.Run(new Form1());
}
public Form1() {
Button button=new Button();
button.Text = "Start thread";
button.Click += new System.EventHandler(button_Click);
Controls.Add(button);
}
private void button_Click(object sender, System.EventArgs e) {
(new Thread(new ThreadStart(StartThread))).Start();
}
private void StartThread() {
UserControl1 userControl1=new UserControl1();
userControl1.Top=24;
userControl1.UselessFunction();
Invoke(new AddControl_Delegate(AddControl),new object[1] {userControl1});
}
private delegate void AddControl_Delegate(UserControl1 control);
private void AddControl(UserControl1 control) {
Controls.Add(control);
}
}

public class UserControl1 : UserControl {
private Button button=new Button();
public UserControl1() {
button.Text = "Success";
Controls.Add(button);
}
public void UselessFunction() {
button.Visible=false;
button.Visible=true;
}
}
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

You should handle all the UI related code in the main thread, if you want to
create a control do so in the main thread, you can assure that a method runs
on it using Control.Invoke ( it will run the method in the thread that
created the control originally, as you only created in the main thread that
does the trick ).

Hope this help,
 
L

Ludovic SOEUR

Thanks for your answer.
You were right, the control must be created in the main thread using
Control.Invoke.
But, after a lot of work, I found there was something more tricky : before
adding the control, it MUST be created with function CreateControl in the
main thread to ensure that all window handles are owned by the main thread.

Here is the source code of the function called by Invoke in order to create
and attach properly the control :

private UserControl1 CreateControl_Proc() {
UserControl1 uc=new UserControl1();
uc.CreateControl();
Controls.Add(uc);
return uc;
}

Thanks Ignacio for your answer that helped me to find a solution.
Sincerely,

Ludovic Soeur.



Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

You should handle all the UI related code in the main thread, if you want to
create a control do so in the main thread, you can assure that a method runs
on it using Control.Invoke ( it will run the method in the thread that
created the control originally, as you only created in the main thread that
does the trick ).

Hope this help,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



Ludovic SOEUR said:
Have everyone tried to create controls in separated threads ? I have a
problem that I do not understand.
To simplify the explanations, I wrote theses few lines to show an example
of
the problem.
This program do nothing more than showing a button "Start thread". When it
is pushed, a new thread is started in which a usercontrol is created,
showing another button. That's all.
Everything works, but, when like this source code I put the line (line 23)
userControl1.UselessFunction();
it fails (lock for a very very long time) and I have to kill the task.
This useless function only shows the button ! That 's strange, isn't it ?

I tried to move the line after the line 24
Invoke(new AddControl_Delegate(AddControl),new object[1] {userControl1});
and in this case, it works perfectly !

Could someone help me please ?

Thanks,
Ludovic SOEUR.

Here is the source code :

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

public class Form1 : Form {
[STAThread]
static void Main() {
Application.Run(new Form1());
}
public Form1() {
Button button=new Button();
button.Text = "Start thread";
button.Click += new System.EventHandler(button_Click);
Controls.Add(button);
}
private void button_Click(object sender, System.EventArgs e) {
(new Thread(new ThreadStart(StartThread))).Start();
}
private void StartThread() {
UserControl1 userControl1=new UserControl1();
userControl1.Top=24;
userControl1.UselessFunction();
Invoke(new AddControl_Delegate(AddControl),new object[1] {userControl1});
}
private delegate void AddControl_Delegate(UserControl1 control);
private void AddControl(UserControl1 control) {
Controls.Add(control);
}
}

public class UserControl1 : UserControl {
private Button button=new Button();
public UserControl1() {
button.Text = "Success";
Controls.Add(button);
}
public void UselessFunction() {
button.Visible=false;
button.Visible=true;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top