Problem creating controls with multi-threading

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ludovic SOEUR

    Problem creating controls with multi-threading

    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.Us elessFunction() ;
    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_Dele gate(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.Threadin g;

    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.EventHan dler(button_Cli ck);
    Controls.Add(bu tton);
    }
    private void button_Click(ob ject sender, System.EventArg s e) {
    (new Thread(new ThreadStart(Sta rtThread))).Sta rt();
    }
    private void StartThread() {
    UserControl1 userControl1=ne w UserControl1();
    userControl1.To p=24;
    userControl1.Us elessFunction() ;
    Invoke(new AddControl_Dele gate(AddControl ),new object[1] {userControl1}) ;
    }
    private delegate void AddControl_Dele gate(UserContro l1 control);
    private void AddControl(User Control1 control) {
    Controls.Add(co ntrol);
    }
    }

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


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

    #2
    Re: Problem creating controls with multi-threading

    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" <Ludovic_SOEUR@ hotmail.com> wrote in message
    news:uGgN7GZ8EH A.1204@TK2MSFTN GP10.phx.gbl...[color=blue]
    > 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.Us elessFunction() ;
    > 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_Dele gate(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.Threadin g;
    >
    > 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.EventHan dler(button_Cli ck);
    > Controls.Add(bu tton);
    > }
    > private void button_Click(ob ject sender, System.EventArg s e) {
    > (new Thread(new ThreadStart(Sta rtThread))).Sta rt();
    > }
    > private void StartThread() {
    > UserControl1 userControl1=ne w UserControl1();
    > userControl1.To p=24;
    > userControl1.Us elessFunction() ;
    > Invoke(new AddControl_Dele gate(AddControl ),new object[1] {userControl1}) ;
    > }
    > private delegate void AddControl_Dele gate(UserContro l1 control);
    > private void AddControl(User Control1 control) {
    > Controls.Add(co ntrol);
    > }
    > }
    >
    > public class UserControl1 : UserControl {
    > private Button button=new Button();
    > public UserControl1() {
    > button.Text = "Success";
    > Controls.Add(bu tton);
    > }
    > public void UselessFunction () {
    > button.Visible= false;
    > button.Visible= true;
    > }
    > }
    >
    >[/color]


    Comment

    • Ludovic SOEUR

      #3
      Re: Problem creating controls with multi-threading

      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_P roc() {
      UserControl1 uc=new UserControl1();
      uc.CreateContro l();
      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 )" <ignacio.mach in AT dot.state.fl.us > a
      écrit dans le message de news:%23dxxiSc8 EHA.3700@tk2msf tngp13.phx.gbl. ..[color=blue]
      > Hi,
      >
      > You should handle all the UI related code in the main thread, if you want[/color]
      to[color=blue]
      > create a control do so in the main thread, you can assure that a method[/color]
      runs[color=blue]
      > 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[/color]
      that[color=blue]
      > does the trick ).
      >
      > Hope this help,
      >
      > --
      > Ignacio Machin,
      > ignacio.machin AT dot.state.fl.us
      > Florida Department Of Transportation
      >
      >
      >
      > "Ludovic SOEUR" <Ludovic_SOEUR@ hotmail.com> wrote in message
      > news:uGgN7GZ8EH A.1204@TK2MSFTN GP10.phx.gbl...[color=green]
      > > 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[/color][/color]
      example[color=blue][color=green]
      > > of
      > > the problem.
      > > This program do nothing more than showing a button "Start thread". When[/color][/color]
      it[color=blue][color=green]
      > > 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[/color][/color]
      23)[color=blue][color=green]
      > > userControl1.Us elessFunction() ;
      > > 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[/color][/color]
      ?[color=blue][color=green]
      > >
      > > I tried to move the line after the line 24
      > > Invoke(new AddControl_Dele gate(AddControl ),new object[1][/color][/color]
      {userControl1}) ;[color=blue][color=green]
      > > 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.Threadin g;
      > >
      > > 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.EventHan dler(button_Cli ck);
      > > Controls.Add(bu tton);
      > > }
      > > private void button_Click(ob ject sender, System.EventArg s e) {
      > > (new Thread(new ThreadStart(Sta rtThread))).Sta rt();
      > > }
      > > private void StartThread() {
      > > UserControl1 userControl1=ne w UserControl1();
      > > userControl1.To p=24;
      > > userControl1.Us elessFunction() ;
      > > Invoke(new AddControl_Dele gate(AddControl ),new object[1][/color][/color]
      {userControl1}) ;[color=blue][color=green]
      > > }
      > > private delegate void AddControl_Dele gate(UserContro l1 control);
      > > private void AddControl(User Control1 control) {
      > > Controls.Add(co ntrol);
      > > }
      > > }
      > >
      > > public class UserControl1 : UserControl {
      > > private Button button=new Button();
      > > public UserControl1() {
      > > button.Text = "Success";
      > > Controls.Add(bu tton);
      > > }
      > > public void UselessFunction () {
      > > button.Visible= false;
      > > button.Visible= true;
      > > }
      > > }
      > >
      > >[/color]
      >
      >[/color]


      Comment

      Working...