Ich versuche, Threads zu verwenden und zu verhindern, dass das Programm einfriert, während der Thread beschäftigt ist. Es sollte den Fortschritt anzeigen (Schreiben von Nullen/1) und nicht nur das Ergebnis nach dessen Beendigung zeigen, sondern das Formular in der Zwischenzeit einfrieren.C# Threading mit Aufruf, Einfrieren des Formulars
In dem aktuellen Programm versuche ich in ein Textfeld zu schreiben, und tatsächlich einen konstanten Fortschritt zu sehen, und das Formular kann nicht durch die Aufgaben des anderen Threads beeinflusst werden.
Was ich jetzt habe ist, kann ich in ein Textfeld mit einem Thread schreiben mit invoke, aber es zeigt nur das Ergebnis (Form friert, während Thread beschäftigt ist), und das Formular friert ein.
Formular Bild:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace MultiThreading
{
public partial class MultiThreading : Form
{
public MultiThreading()
{
InitializeComponent();
}
Thread writeOne, writeTwo;
private void writeText(TextBox textBox, string text)
{
if (textBox.InvokeRequired)
{
textBox.BeginInvoke((MethodInvoker)delegate()
{
for (int i = 0; i < 500; i++)
{
textBox.Text += text;
}
});
}
else
{
for (int i = 0; i < 500; i++)
{
textBox.Text += text;
}
}
}
private void btnWrite1_Click(object sender, EventArgs e)
{
writeOne = new Thread(() => writeText(txtOutput1, "0"));
writeOne.Start();
}
private void btnWrite2_Click(object sender, EventArgs e)
{
writeTwo = new Thread(() => writeText(txtOutput2, "1"));
writeTwo.Start();
}
private void btnClear1_Click(object sender, EventArgs e)
{
txtOutput1.Clear();
}
private void btnClear2_Click(object sender, EventArgs e)
{
txtOutput2.Clear();
}
private void btnWriteBoth_Click(object sender, EventArgs e)
{
writeOne = new Thread(() => writeText(txtOutput1, "0"));
writeTwo = new Thread(() => writeText(txtOutput2, "1"));
writeOne.Start();
writeTwo.Start();
}
private void btnClearBoth_Click(object sender, EventArgs e)
{
txtOutput1.Clear();
txtOutput2.Clear();
}
}
}
EDIT:
Btw für jedermann, ich bin neu zu Multithreading fragen, und ich versuche nur, ein kleines Programm zu schreiben, das zu verstehen, beste Möglichkeit, dies zu tun.
Ich verstehe, dass mein vorheriger Aufruf nicht wirklich geholfen hat, weil ich dem Formular noch immer keine Chance gab, es zu aktualisieren, also kam es dorthin.
Ok, so läuft 1 Thread wie dieser funktioniert, aber immer noch mehrere Threads zusammen laufen, wird das Formular nicht aktualisieren, bis nach dem Thread fertig ist.
Ich habe eine thread.sleep() hinzugefügt, so dass ich versuchen kann, während des Schreibens zu löschen, um zu sehen, ob ich das Formular noch verwenden kann.
Wenn ich in 1 Textbox schreibe, kann ich beim Schreiben immer noch den Bildschirm löschen.
Aber sobald ich 2 Threads verwende, kann ich das Formular nicht mehr verwenden, bis der Thread abgeschlossen ist, und gibt die Ausgabe.
private void writeText(TextBox textBox, string text)
{
for (int i = 0; i < 500; i++)
{
Invoke(new MethodInvoker(() =>
{
textBox.Text += text;
Thread.Sleep(2);
}));
}
}
(Wenn ich auf diese völlig falsch bin ich nicht dagegen durch einige Beispiele/Threads zu lesen ist, versuche ich immer noch zu sehen, was der beste Weg, dies zu tun, neben einem Background)
EDIT 2:
ich habe die Anzahl der Invokes reduziert durch Verringerung der Menge zu schreiben, aber Verzögerung zu erhöhen, um die gleiche Wirkung der ständigen schreiben geben, nur um die Last zu verringern.
private void writeText(TextBox textBox, string text)
{
for (int i = 0; i < 500; i++)
{
Invoke(new MethodInvoker(() =>
{
textBox.Text += text;
Thread.Sleep(2);
}));
}
}
EDIT 3:
Sumeet Das Beispiel arbeitet
Application.DoEvents mit();
(die s bemerken, ist .DoEvent nicht, Tippfehler wahrscheinlich: P), mehrere Saiten gleichzeitig & Schreiben sie den Fortschritt zeigen, die nicht nur das Ergebnis.
So aktualisieren-Code wieder :)
* eine neue Schaltfläche Mit 5 Verknüpfungen zu erstellen, die eine Zufallszahl an den beiden Textfelder
private void writeText(TextBox textBox, string text)
{
for (int i = 0; i < 57; i++)
{
Invoke(new MethodInvoker(() =>
{
textBox.Text += text;
Thread.Sleep(5);
Application.DoEvents();
}));
}
}
private void btnNewThread_Click(object sender, EventArgs e)
{
Random random = new Random();
int[] randomNumber = new int[5];
for (int i = 0; i < 5; i++)
{
randomNumber[i] = random.Next(2, 9);
new Thread(() => writeText(txtOutput1, randomNumber[i-1].ToString())).Start();
new Thread(() => writeText(txtOutput2, randomNumber[i-1].ToString())).Start();
}
}
Betrachten Sie mit [ 'BackgroundWorker'] (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx), wenn Sie einen langlaufende Prozess läuft haben im Hintergrund und die Benutzeroberfläche muss reaktionsfähig bleiben. –
@RobertHarvey Das würde diesem bestimmten Beispiel nicht wirklich helfen. – Servy
@Servy Dieses spezielle Beispiel scheint ... kaputt zu sein. Und erfunden. Es gibt einen ausgetretenen Pfad für diese Art von Dingen. –