Ich war ein einfaches WinForm der Zusammenstellung, die eine Anzahl von Threads zu Schleife 0-10000 laichen würde - der Zweck dieser - von Windows zu verlangsamen, um einige anderen Programmen langsam laufen zu lassen.C# Aktualisierung TextBox von mehreren Threads
Grundsätzlich hat die Form ein Textfeld, das ich zu dem Schleifenindex schreiben will von jedem Thread. Alles war in Ordnung für einen einzelnen Thread, aber da ich mehr Threads eingeführt habe, würde ich scheinen, um die Anwendung zu hängen, wenn ich auf den Stop-Button klicke - ich bin nicht sicher, wohin ich von hier aus gehen soll.
Meine Probe wird wahrscheinlich nicht gut geschrieben. Ich möchte ein besseres Verständnis von Multithreading, Deadlocks usw. bekommen. Ich habe mich in der Vergangenheit ein wenig mit BackgroundWorker beschäftigt, mache aber Java die meiste Zeit der letzten 2+ Jahre.
Form1.cs
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;
}
aktualisieren Wenn ich die Sperre auf die sonst in der Updateverfahren zu bewegen und einen Thread hinzufügen .Schlaf (20); in der Schleife, dann ist meine GUI reaktionsfähiger und ich kann auf die Schaltfläche Stop klicken und das Formular verschieben.
Jedes Feedback wird Behebungen geschätzt.
könnte eine schlechte Antwort sein oder überhaupt keine Antwort, warum nicht die Update-Funktion synchronisiert? –
Immer noch der gleiche Effekt mit vielen Threads. – Andez
OK, also machen Sie blockierende Anrufe, deshalb friert die Benutzeroberfläche ein und führt einen asynchronen Anruf bei der blockierenden Funktion aus. –