我正在制作一个简单的WinForm,该程序会启动多个线程来循环从0到10000。目的是通过减缓Windows来使其他程序运行变慢。
基本上,该表单有一个文本框,我想从每个线程将循环索引写入该文本框。当只有一个线程时一切正常,但自从我引入了更多线程后,当我点击停止按钮时,应用程序会卡住,我不确定接下来该怎么做。
我的示例可能没有编写好。我想更好地了解多线程、死锁等。我之前尝试过使用BackgroundWorker,但在过去的两年中,我一直在使用Java。
如果我将锁移动到UpdateText方法中的else语句,并在循环中添加Thread.Sleep(20);,则我的GUI更加响应,我可以点击停止按钮并移动窗体。欢迎提供任何反馈和修复建议。
基本上,该表单有一个文本框,我想从每个线程将循环索引写入该文本框。当只有一个线程时一切正常,但自从我引入了更多线程后,当我点击停止按钮时,应用程序会卡住,我不确定接下来该怎么做。
我的示例可能没有编写好。我想更好地了解多线程、死锁等。我之前尝试过使用BackgroundWorker,但在过去的两年中,我一直在使用Java。
public delegate void SetTextDelegate(string text);
public partial class Form1 : Form
{
private Thread[] _slow;
private object lockTextBox = new object();
public Form1()
{
InitializeComponent();
}
#region Event Handlers
private void ui_btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void ui_btnStart_Click(object sender, EventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
_slow = new Thread[ (int) numNoOfTheads.Value ];
for( int i = 0; i < numNoOfTheads.Value; i++)
{
_slow[i] = new Thread(ThreadRunLoop);
_slow[i].Start();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
}
private void ui_btnStop_Click(object sender, EventArgs e)
{
if (_slow != null)
{
StopAllThreads();
}
}
private void ui_btnClear_Click(object sender, EventArgs e)
{
this.textBox1.Clear();
}
#endregion
protected void ThreadRunLoop()
{
try
{
for (int i = 0; i < 10000; i++)
{
UpdateText("Loop " + i + " for " + Thread.CurrentThread.ManagedThreadId);
}
}
catch (ThreadInterruptedException ex)
{
Console.WriteLine("Thread has been interrupted.");
}
}
private void UpdateText(string text)
{
//lock (lockTextBox)
//{
if (textBox1.InvokeRequired)
{
textBox1.Invoke(new SetTextDelegate(UpdateText), text);
}
else
{
textBox1.SuspendLayout();
textBox1.Text = textBox1.Text + text + System.Environment.NewLine;
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.ResumeLayout();
}
//}
}
private void StopAllThreads()
{
for (int i = 0; i < _slow.Length; i++)
{
if (_slow[i] != null)
{
_slow[i].Interrupt();
_slow[i] = null;
}
}
_slow = null;
}
}
Form1.Designer.cs
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (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.ui_btnClose = new System.Windows.Forms.Button();
this.ui_btnStart = new System.Windows.Forms.Button();
this.ui_btnStop = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.ui_btnClear = new System.Windows.Forms.Button();
this.numNoOfTheads = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numNoOfTheads)).BeginInit();
this.SuspendLayout();
//
// ui_btnClose
//
this.ui_btnClose.Location = new System.Drawing.Point(433, 268);
this.ui_btnClose.Name = "ui_btnClose";
this.ui_btnClose.Size = new System.Drawing.Size(75, 23);
this.ui_btnClose.TabIndex = 0;
this.ui_btnClose.Text = "Close";
this.ui_btnClose.UseVisualStyleBackColor = true;
this.ui_btnClose.Click += new System.EventHandler(this.ui_btnClose_Click);
//
// ui_btnStart
//
this.ui_btnStart.Location = new System.Drawing.Point(12, 12);
this.ui_btnStart.Name = "ui_btnStart";
this.ui_btnStart.Size = new System.Drawing.Size(75, 23);
this.ui_btnStart.TabIndex = 1;
this.ui_btnStart.Text = "Start";
this.ui_btnStart.UseVisualStyleBackColor = true;
this.ui_btnStart.Click += new System.EventHandler(this.ui_btnStart_Click);
//
// ui_btnStop
//
this.ui_btnStop.Location = new System.Drawing.Point(12, 41);
this.ui_btnStop.Name = "ui_btnStop";
this.ui_btnStop.Size = new System.Drawing.Size(75, 23);
this.ui_btnStop.TabIndex = 2;
this.ui_btnStop.Text = "Stop";
this.ui_btnStop.UseVisualStyleBackColor = true;
this.ui_btnStop.Click += new System.EventHandler(this.ui_btnStop_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(93, 12);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(415, 241);
this.textBox1.TabIndex = 3;
//
// ui_btnClear
//
this.ui_btnClear.Location = new System.Drawing.Point(352, 268);
this.ui_btnClear.Name = "ui_btnClear";
this.ui_btnClear.Size = new System.Drawing.Size(75, 23);
this.ui_btnClear.TabIndex = 4;
this.ui_btnClear.Text = "Clear";
this.ui_btnClear.UseVisualStyleBackColor = true;
this.ui_btnClear.Click += new System.EventHandler(this.ui_btnClear_Click);
//
// numNoOfTheads
//
this.numNoOfTheads.Location = new System.Drawing.Point(12, 98);
this.numNoOfTheads.Name = "numNoOfTheads";
this.numNoOfTheads.Size = new System.Drawing.Size(74, 20);
this.numNoOfTheads.TabIndex = 5;
this.numNoOfTheads.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(9, 82);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(83, 13);
this.label1.TabIndex = 6;
this.label1.Text = "No. Of Threads:";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(520, 303);
this.Controls.Add(this.label1);
this.Controls.Add(this.numNoOfTheads);
this.Controls.Add(this.ui_btnClear);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.ui_btnStop);
this.Controls.Add(this.ui_btnStart);
this.Controls.Add(this.ui_btnClose);
this.Name = "Form1";
this.Text = "Slow My Machine";
this.Load += new System.EventHandler(this.Form1_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.numNoOfTheads)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button ui_btnClose;
private System.Windows.Forms.Button ui_btnStart;
private System.Windows.Forms.Button ui_btnStop;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button ui_btnClear;
private System.Windows.Forms.NumericUpDown numNoOfTheads;
private System.Windows.Forms.Label label1;
}
如果我将锁移动到UpdateText方法中的else语句,并在循环中添加Thread.Sleep(20);,则我的GUI更加响应,我可以点击停止按钮并移动窗体。欢迎提供任何反馈和修复建议。