スレッドを使用して、スレッドがビジーなときにプログラムがフリーズしないようにしようとしています。進行状況 (0 と 1 の書き込み) を表示し、完了後に結果を表示するだけでなく、その間にフォームをフリーズする必要があります。
現在のプログラムでは、テキストボックスに書き込もうとしていますが、実際には一定の進行状況が見られ、フォームは他のスレッドのタスクの影響を受けません。
私が今持っているのは、呼び出しを使用してスレッドでテキストボックスに書き込むことができるということですが、結果のみを表示し (スレッドがビジー状態のときにフォームがフリーズします)、フォームがフリーズします。
フォーム画像:
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();
}
}
}
編集:
ところで、私はマルチスレッドが初めてで、これを行うための最良の方法を理解するために小さなプログラムを作成しようとしています。
フォームを更新する機会をまだ与えていなかったため、以前の呼び出しが実際には役に立たなかったことを理解しています。
このように 1 つのスレッドを実行しても機能しますが、複数のスレッドを一緒に実行すると、スレッドが完了するまでフォームが更新されません。
thread.sleep() を追加したので、書き込み中にクリアして、フォームをまだ使用できるかどうかを確認できます。
1つのテキストボックスに書き込むとき、書き込み中に画面をクリアできます。
しかし、2 つのスレッドを使用すると、スレッドが完了して出力が得られるまでフォームを使用できなくなります。
private void writeText(TextBox textBox, string text)
{
for (int i = 0; i < 500; i++)
{
Invoke(new MethodInvoker(() =>
{
textBox.Text += text;
Thread.Sleep(2);
}));
}
}
(私がこれについて完全に間違っている場合、いくつかの例/スレッドを読む必要はありません。バックグラウンドワーカー以外に、これを行うための最良の方法は何かをまだ確認しようとしています)
編集2:
書き込み量を減らすことで呼び出しの数を減らしましたが、遅延を増やして一定の書き込みと同じ効果を与え、負荷を減らすだけです。
private void writeText(TextBox textBox, string text)
{
for (int i = 0; i < 500; i++)
{
Invoke(new MethodInvoker(() =>
{
textBox.Text += text;
Thread.Sleep(2);
}));
}
}
編集3:
Sumeet の例は、
Application.DoEvents();
(s、.DoEventが機能しないことに注意してください。おそらくタイプミスです:P)、複数の文字列を同時に書き込み、結果だけでなく進行状況を表示します。
だからコードをもう一度更新してください:)
*新しいボタンを使用して、両方のテキスト ボックスに乱数を書き込む 5 つのスレッドを作成する
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();
}
}