using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;namespace ResearchControl
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private delegate void AddControlsInvoker(System.Windows.Forms.Control[] controls); private System.Collections.ArrayList threadList; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent(); //
// TODO: Add any constructor code after InitializeComponent call
//
threadList = new System.Collections.ArrayList();
} /// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panel1
//
this.panel1.Location = new System.Drawing.Point(0, 40);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(584, 424);
this.panel1.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(24, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Control1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(128, 16);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "Control2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(232, 16);
this.button3.Name = "button3";
this.button3.TabIndex = 3;
this.button3.Text = "Control3";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(584, 461);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false); }
#endregion /// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
} private void button1_Click(object sender, System.EventArgs e)
{
Thread thread = null;
for(int i = threadList.Count - 1; i >= 0; i--)
{
thread = (Thread)threadList[i];
if (thread.IsAlive)
thread.Abort();
threadList.RemoveAt(i);
} panel1.Controls.Clear(); ThreadStart threadStart = new ThreadStart(InitializeControl11);
thread = new Thread(threadStart);
thread.Start();
threadList.Add(thread); threadStart = new ThreadStart(InitializeControl12);
thread = new Thread(threadStart);
thread.Start();
threadList.Add(thread);
} private void button2_Click(object sender, System.EventArgs e)
{
Label waitLabel = new Label();
waitLabel.Location = new System.Drawing.Point(160, 64);
waitLabel.Size = new System.Drawing.Size(288, 23);
waitLabel.Name = "label1";
waitLabel.TabIndex = 0;
waitLabel.Text = "Waiting for intialize controls...";
panel1.Controls.Add(waitLabel);
} private void button3_Click(object sender, System.EventArgs e)
{
} private void AddControls(System.Windows.Forms.Control[] controls)
{
panel1.Controls.AddRange(controls);
}
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;namespace ResearchControl
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private delegate void AddControlsInvoker(System.Windows.Forms.Control[] controls); private System.Collections.ArrayList threadList; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent(); //
// TODO: Add any constructor code after InitializeComponent call
//
threadList = new System.Collections.ArrayList();
} /// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panel1
//
this.panel1.Location = new System.Drawing.Point(0, 40);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(584, 424);
this.panel1.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(24, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Control1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(128, 16);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "Control2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(232, 16);
this.button3.Name = "button3";
this.button3.TabIndex = 3;
this.button3.Text = "Control3";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(584, 461);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false); }
#endregion /// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
} private void button1_Click(object sender, System.EventArgs e)
{
Thread thread = null;
for(int i = threadList.Count - 1; i >= 0; i--)
{
thread = (Thread)threadList[i];
if (thread.IsAlive)
thread.Abort();
threadList.RemoveAt(i);
} panel1.Controls.Clear(); ThreadStart threadStart = new ThreadStart(InitializeControl11);
thread = new Thread(threadStart);
thread.Start();
threadList.Add(thread); threadStart = new ThreadStart(InitializeControl12);
thread = new Thread(threadStart);
thread.Start();
threadList.Add(thread);
} private void button2_Click(object sender, System.EventArgs e)
{
Label waitLabel = new Label();
waitLabel.Location = new System.Drawing.Point(160, 64);
waitLabel.Size = new System.Drawing.Size(288, 23);
waitLabel.Name = "label1";
waitLabel.TabIndex = 0;
waitLabel.Text = "Waiting for intialize controls...";
panel1.Controls.Add(waitLabel);
} private void button3_Click(object sender, System.EventArgs e)
{
} private void AddControls(System.Windows.Forms.Control[] controls)
{
panel1.Controls.AddRange(controls);
}
{
System.Windows.Forms.Control[] controls = null; Label waitLabel = new Label();
waitLabel.Location = new System.Drawing.Point(160, 64);
waitLabel.Size = new System.Drawing.Size(288, 23);
waitLabel.Name = "label1";
waitLabel.TabIndex = 0;
waitLabel.Text = "Waiting for intialize controls...";
controls = new System.Windows.Forms.Control[] { waitLabel }; lock(panel1)
{
// panel1.SuspendLayout();
panel1.Invoke(new AddControlsInvoker(AddControls), new object[] {controls});
// panel1.ResumeLayout();
}
#region
//
// label1
//
Label label1 = new Label();
label1.Location = new System.Drawing.Point(32, 32);
label1.Name = "label1";
label1.TabIndex = 0;
label1.Text = "label1";
//
// label2
//
Label label2 = new Label();
label2.Location = new System.Drawing.Point(170, 32);
label2.Name = "label2";
label2.TabIndex = 1;
label2.Text = "label2";
//
// label3
//
Label label3 = new Label();
label3.Location = new System.Drawing.Point(308, 32);
label3.Name = "label3";
label3.TabIndex = 2;
label3.Text = "label3";
//
// label4
//
Label label4 = new Label();
label4.Location = new System.Drawing.Point(446, 32);
label4.Name = "label4";
label4.TabIndex = 3;
label4.Text = "label4";
//
// textBox1
//
TextBox textBox1 = new TextBox();
textBox1.Location = new System.Drawing.Point(32, 96);
textBox1.Name = "textBox1";
textBox1.TabIndex = 4;
textBox1.Text = "textBox1";
//
// textBox2
//
TextBox textBox2 = new TextBox();
textBox2.Location = new System.Drawing.Point(170, 96);
textBox2.Name = "textBox2";
textBox2.TabIndex = 5;
textBox2.Text = "textBox2";
//
// textBox3
//
TextBox textBox3 = new TextBox();
textBox3.Location = new System.Drawing.Point(308, 96);
textBox3.Name = "textBox3";
textBox3.TabIndex = 6;
textBox3.Text = "textBox3";
//
// textBox4
//
TextBox textBox4 = new TextBox();
textBox4.Location = new System.Drawing.Point(446, 96);
textBox4.Name = "textBox4";
textBox4.TabIndex = 7;
textBox4.Text = "textBox4";
#endregion controls = new System.Windows.Forms.Control[] { label1, label2, label3, label4,
textBox1, textBox2, textBox3, textBox4};
lock(panel1)
{
// panel1.SuspendLayout();
panel1.Invoke(new AddControlsInvoker(AddControls), new object[] {controls});
panel1.Controls.Remove(waitLabel);
// panel1.ResumeLayout();
}
}
private void InitializeControl12()
{
System.Windows.Forms.Control[] controls = null; Label waitLabel = new Label();
waitLabel.Location = new System.Drawing.Point(152, 312);
waitLabel.Size = new System.Drawing.Size(288, 23);
waitLabel.Name = "label1";
waitLabel.TabIndex = 0;
waitLabel.Text = "Waiting for intialize controls...";
controls = new System.Windows.Forms.Control[] { waitLabel }; lock(panel1)
{
// panel1.SuspendLayout();
panel1.Invoke(new AddControlsInvoker(AddControls), new object[] {controls});
// panel1.ResumeLayout();
}
#region
//
// label1
//
Label label1 = new Label();
label1.Location = new System.Drawing.Point(24, 280);
label1.Name = "label1";
label1.TabIndex = 0;
label1.Text = "label1";
//
// label2
//
Label label2 = new Label();
label2.Location = new System.Drawing.Point(160, 280);
label2.Name = "label2";
label2.TabIndex = 1;
label2.Text = "label2";
//
// label3
//
Label label3 = new Label();
label3.Location = new System.Drawing.Point(296, 280);
label3.Name = "label3";
label3.TabIndex = 2;
label3.Text = "label3";
//
// label4
//
Label label4 = new Label();
label4.Location = new System.Drawing.Point(440, 280);
label4.Name = "label4";
label4.TabIndex = 3;
label4.Text = "label4";
//
// textBox1
//
TextBox textBox1 = new TextBox();
textBox1.Location = new System.Drawing.Point(24, 344);
textBox1.Name = "textBox1";
textBox1.TabIndex = 4;
textBox1.Text = "textBox1";
//
// textBox2
//
TextBox textBox2 = new TextBox();
textBox2.Location = new System.Drawing.Point(160, 344);
textBox2.Name = "textBox2";
textBox2.TabIndex = 5;
textBox2.Text = "textBox2";
//
// textBox3
//
TextBox textBox3 = new TextBox();
textBox3.Location = new System.Drawing.Point(296, 344);
textBox3.Name = "textBox3";
textBox3.TabIndex = 6;
textBox3.Text = "textBox3";
//
// textBox4
//
TextBox textBox4 = new TextBox();
textBox4.Location = new System.Drawing.Point(440, 344);
textBox4.Name = "textBox4";
textBox4.TabIndex = 7;
textBox4.Text = "textBox4"; #endregion controls = new System.Windows.Forms.Control[] { label1, label2, label3, label4,
textBox1, textBox2, textBox3, textBox4};
lock(panel1)
{
panel1.SuspendLayout();
panel1.Invoke(new AddControlsInvoker(AddControls), new object[] {controls});
panel1.Controls.Remove(waitLabel);
panel1.ResumeLayout();
}
}
}
}
private void AddControls(System.Windows.Forms.Control[] controls)
{
Label waitLabel = new Label();
waitLabel.Location = new System.Drawing.Point(160, 64);
waitLabel.Size = new System.Drawing.Size(288, 23);
waitLabel.Name = "label1";
waitLabel.TabIndex = 0;
waitLabel.Text = "Waiting for intialize controls...";
panel1.Controls.AddRange(new System.Windows.Forms.Control[] { waitLabel });
}
1) 由单个线程生成窗口,极其所有子窗口和控件。
2) 这个线程作为整个窗口结构的owner,控制窗口(和子窗口)的消息循环。
3)仅有这个线程可以直接安全的访问控件,其他线程必须通过某种线程通信机制来访问控件。(在.NET中,该线程可以调用控件的成员方法,而其他线程必须使用Control.Invoke)。你上面代码的问题是不符合这种基本要求:不能在两个子线程中为窗口添加新的控件,而应该使用某种线程通信,通知UI线程创建这些控件。
to sqhua(拉长弓兮射天狼):程序其实不长,有兴趣的话可以按照我上面说的方法在你的机器上试试,大部分创建控件的方法可以缩起来不看。to qqchen79(知秋一叶 [MSMVP]):你的答复很有道理,但是我认为:
1。虽然控件的构造是在其他线程里完成的,但真正完成街面上的工作是在主线程完成的,而线程退出并不会销毁对象,这个对显示或者Control.Invoke有影响吗?
2。我现在要做的就是要在其他几个线程里完成控件的创建的研究工作,为什么我执行一次Control.Invoke就会正常呢?会带来什么负面或不可预测的影响吗(除消息之外)? to ssdjmcj8048(不爱我的我不爱): 这只是个同步异步的问题,两种情况都试过,结果一样。 再问个问题,在其他线程里访问控件都必须用Control.Invoke吗?很多操作,比如Panel.Controls.Remove,可以在其他线程里完成,结果也正常,会不会有什么不可预测的问题呢?