Frage

Ich habe einige ungelöste Problem mit Threads. Es ist mein erstes Mal, es zu tun. Ich weiß, wie einen Thread zu verwenden, in einem Textfeld zu schreiben, aber ich habe keine Ahnung, wie zwei von ihnen zu verwenden, um den Job zu erledigen. hat jemand eine Ahnung, was muß ich tun zu können, zwei Threads verwenden, um die gleiche textBox, aber nicht in der gleichen Zeit zu schreiben. Danke.

War es hilfreich?

Lösung

Hier ist ein Beispiel, die zwei Threads verwendet, um Zufallszahl zu einem mehrzeiligen Textfeld zu schreiben. Als Brandon und Jon B erwähnt, müssen Sie Invoke () verwenden, um die Anrufe an den GUI-Thread serialisiert werden.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    Random m_random = new Random((int)DateTime.Now.Ticks);
    ManualResetEvent m_stopThreadsEvent = new ManualResetEvent(false);

    private void buttonStart_Click(object sender, EventArgs e)
    {
        Thread t1 = new Thread(new ThreadStart(ThreadOne));
        Thread t2 = new Thread(new ThreadStart(ThreadTwo));

        t1.Start();
        t2.Start();
    }

    private void ThreadOne()
    {
        for(;;)
        {
            int n = m_random.Next(1000);
            AppendText(String.Format("One: {0}\r\n", n));
            if(m_stopThreadsEvent.WaitOne(n))
            {
                break;
            }
        }
    }

    private void ThreadTwo()
    {
        for(;;)
        {
            int n = m_random.Next(1000);
            AppendText(String.Format("Two: {0}\r\n", n));
            if(m_stopThreadsEvent.WaitOne(n))
            {
                break;
            }
        }
    }

    delegate void AppendTextDelegate(string text);

    private void AppendText(string text)
    {
        if(textBoxLog.InvokeRequired)
        {
            textBoxLog.Invoke(new AppendTextDelegate(this.AppendText), new object[] { text });
        }
        else
        {
            textBoxLog.Text = textBoxLog.Text += text;
        }
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        m_stopThreadsEvent.Set();
    }
}

Andere Tipps

Eine weitere Option ist ein Thema Callback-Methode zu verwenden. Dies ist ein Verfahren, das auf dem Haupt-Thread existiert, aber, wenn einen neuen Thread Erstellen geben Sie einen Griff / Hinweis auf dieses Verfahren. Dies ermöglicht es der zweite Thread die Methode auf dem Haupt-Thread und die Funktionalität zu nennen die Textbox zu aktualisieren / Check dort sitzen würde.

Schauen Sie in die Delegierten zwischen Threads übergeben.

Eine Option, die Sie tun konnten, ist Nachrichten auf ein Queue-Objekt drücken und einen Timer auf dem Windows-Formular verwenden, um Nachrichten aus dieser Warteschlange zu lesen und in das Textfeld schreiben.

Um alles schön zu machen und threadsage könnten Sie das Queue-Objekt sperren beim Lesen und Schreiben zu.

Zum Beispiel:

    private Queue<string> messages = new Queue<string>();

    /// <summary>
    /// Add Message To The Queue
    /// </summary>
    /// <param name="text"></param>
    public void NewMessage(string text)
    {
        lock (messages)
        {
            messages.Enqueue(text);
        }
    }

    private void tmr_Tick(object sender, EventArgs e)
    {
        if (messages.Count == 0) return;
        lock (messages)
        {
            this.textBox.Text += Environment.NewLine + messages;
        }
    }

sicherste Methode ist es, nur 1 haben Gewinde der Lage sein, auf das Textfeld zu arbeiten (oder jedes GUI-Objekt), haben alle anderen Threads, die eine Aktion auf dem Textfeld durchführen müssen, um ihre Bedürfnisse zu dem Thread kommunizieren, die den Text steuert Box.

so Ihre Frage wird wie zwischen Threads zu kommunizieren, dies wird die Sprache / OS spezifisch sein, so dass Sie mehr Informationen zur Verfügung stellen müssen.

Das MSDN-Artikel erklärt, wie die Threadsicherheit Anrufe tätigen zu Fenster Formular-Steuerelemente.

Sie können nur GUI zugreifen Komponenten aus dem Haupt-Thread. Um auf eine Textbox von einem anderen Thread zu schreiben, müssen Sie verwenden BeginInvoke () .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top