Wątki - prosty przykład

0

Witam, od zawsze miałem problem ze zrozumieniem działania wątków. Próbuję napisać na prawdę prosty przykład:

  • dwa przyciski
  • jeden textbox

Chcę, żeby po naciśnięciu jednego z przycisków, co 500ms pojawiał się textboxie "plus", a po naciśnięciu drugiego "minus". Innymi słowy, chcę, żeby te plusy z minusami się przeplatały w jednym tekstboxie.

Próbowałem coś napisać, ale interfejs zamarza, po prostu nie umiem. Mój kod:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace testwatek
{
    public partial class Form1 : Form
    {
        private Thread writePlusThread;
        private Thread writeMinusThread;

        public Form1()
        {
            InitializeComponent();
        }

        public delegate void myDelegate();

        private void btnPlus_Click(object sender, EventArgs e)
        {
            writePlusThread = new Thread(new ThreadStart(writePlus));
            writePlusThread.Start();

        }

        private void btnMinus_Click(object sender, EventArgs e)
        {
            writeMinusThread = new Thread(new ThreadStart(writeMinus));
            writeMinusThread.Start();
        }

        private void writePlus()
        {
            if (txtDzialanieWatkow.InvokeRequired)
            {
                myDelegate mojDelegat = new myDelegate(writePlus);
                Invoke(mojDelegat);
            }
            else
            {
                while (true)
                {
                    txtDzialanieWatkow.Text += "+";
                    txtDzialanieWatkow.Refresh();
                    Thread.Sleep(500);
                }
            }
        }

        private void writeMinus()
        {
            if (txtDzialanieWatkow.InvokeRequired)
            {
                myDelegate mojDelegat = new myDelegate(writeMinus);
                Invoke(mojDelegat);
            }
            else
            {
                while (true)
                {
                    txtDzialanieWatkow.Text += "-";
                    txtDzialanieWatkow.Refresh();
                    Thread.Sleep(500);
                }
            }
        }
    }
}

Mogę prosić o jakąś pomoc? Najlepiej bez odsyłania mnie do google...

1

Same wątki działają jak trzeba, problem jest w Invoke. Ta pomocnicza metoda została stworzona, żeby ułatwić wywołanie dowolnych delegat w kontekście głównego wątku UI właśnie. Wywołując tam Thread.Sleep blokujesz nie te własne wątki, ale ten główny.

Stwórz sobie dodatkową metodę dokonującą tej modyfikacji na UI, którą będzie można wywołać z dowolnego wątku oraz nie będzie blokować wątku UI na dłuższy czas.

Coś w tym stylu.

void AppendToTextBox(string text)
{
    if (InvokeRequired)
        Invoke((Action)(() => AppendToTextBox(text)));
    else
        textBox1.Text += text;
}

I w samych wątkach ją wywołuj:

while (true)
{
    AppendToTextBox("-");
    Thread.Sleep(500);
}

W ten sposób najpierw dokonasz szybkiej modyfikacji textboksa, a potem uśpisz już swój wątek.

1 użytkowników online, w tym zalogowanych: 0, gości: 1