Мне удалось создать простую программу, которая обновляет TextBox из другого потока и класса. Самый простой способ изучить потоки визуальным способом. ;)
Код сделан с документацией от msdn. Он работает, и я не вижу утечки памяти. Но я чувствую, что это можно сделать проще.
Есть два основных класса; Форма и класс BackGround. В классе BackGround есть функция generateStream, которая обновляет TextBox в классе Form через делегат функции updateTextBox.
При нажатии кнопки «Старт» выполняются два действия. Первый generateStream вызывается напрямую. Когда generateStream готов, создается поток, который снова запускает generateStream (через TheFunction). При использовании другого потока TextBox требует решения для вызова.
Все это реализовано и работает. Я думаю, что это довольно много кода и, возможно, можно сделать более чистым.
Функция в основном классе, которая обновляет форму и вызывается обратно.
public void updateTextBox(string strtext)
{
if (this.InvokeRequired) //When calling from another thread; invoke is required.
{
SetTextCallBack cb = new SetTextCallBack(updateTextBox);
this.Invoke(cb, new object[] { strtext });
}
else //Call can be performed safely.
{
textBoxStatus.SelectionStart = textBoxStatus.Text.Length;
textBoxStatus.AppendText(strtext);
textBoxStatus.Update();
}
}
Действия, выполняемые нажатием кнопки.
private void buttonStart_Click(object sender, EventArgs e)
{
buttonStart.Enabled = false;
/*
* Step 1: Let's call the function blocking.
* The GUI will not respond to mouse geastures. Hoover mouse over inputbox to see no change in pointer.
*/
bg.generateStream(numberOfCalls, "GUI Thread: ");
/*
* Step 2: Let's call the function in a seperate thread.
* The GUI will now respond to the mouse. Hoover mouse over inputbox to see pointer change.
*/
Thread sepThread = new Thread(new ThreadStart(this.TheFunction));
sepThread.Start();
buttonStart.Enabled = true;
}
Функция generateStream в классе BackGround.
public void generateStream(int amountOfStreams, string inpString)
{
for (int i = 0; i < amountOfStreams; i++)
{
Thread.Sleep(1000); //Easy does it.
myCallBack(inpString + i.ToString() + System.Environment.NewLine); //This is the text to the Main Form.
}
}
При использовании потока теперь я использую два обратных вызова для обновления TextBox. Один из класса BackGround в Form и один для реализации Invoke. Например, не существует ли семафора-решения, в котором моя функция updateTextBox может иметь доступ только к одному потоку?