Domanda

Ho qualche problema irrisolto con i thread. È la prima volta che lo faccio. So usare un thread per scrivere in una casella di testo, ma non ho idea di come usarne due per fare il lavoro. Qualcuno ha la minima idea di cosa devo fare per poter usare due thread per scrivere nello stesso textBox, ma non nello stesso tempo. Grazie.

È stato utile?

Soluzione

Ecco un esempio che utilizza due thread per scrivere numeri casuali in una casella di testo a più righe. Come notato da Brandon e Jon B, è necessario utilizzare Invoke () per serializzare le chiamate al thread della GUI.

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();
    }
}

Altri suggerimenti

Un'altra opzione è quella di utilizzare un metodo di richiamata di thread. Questo è un metodo esistente sul thread principale, ma quando si crea un nuovo thread si passa un handle / riferimento a questo metodo. Ciò consente al secondo thread di chiamare il metodo sul thread principale e la funzionalità di aggiornamento / controllo della casella di testo rimarrà lì.

Cerca di passare i delegati tra i thread.

Un'opzione che potresti fare è spingere i messaggi su un oggetto Coda e usare un timer nel modulo di Windows per leggere i messaggi da questa coda e scrivere nella casella di testo.

Al fine di rendere tutto bello e threadage è possibile bloccare l'oggetto Queue durante la lettura e la scrittura su di esso.

Ad esempio:

    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;
        }
    }

L'approccio più sicuro è avere solo 1 thread in grado di lavorare sulla casella di testo (o qualsiasi oggetto gui), avere altri thread che devono eseguire un'azione sulla casella di testo per comunicare le loro esigenze al thread che controlla il testo scatola.

quindi la tua domanda diventa come comunicare tra i thread, questo sarà specifico per lingua / SO quindi devi fornire maggiori informazioni.

Questo Articolo MSDN spiega come effettuare chiamate thread-safe a controlli modulo windows.

Puoi accedere ai componenti della GUI solo dal thread principale. Per scrivere in una casella di testo da un altro thread, è necessario utilizzare BeginInvoke () .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top