Question

J'ai un problème non résolu avec les threads. C'est la première fois que je le fais. Je sais comment utiliser un fil pour écrire dans une zone de texte, mais je ne sais pas comment en utiliser deux pour faire le travail. Tout le monde a une idée de ce que je dois faire pour pouvoir utiliser deux threads pour écrire dans la même zone de texte, mais pas dans le même temps. Merci.

Était-ce utile?

La solution

Voici un exemple qui utilise deux threads pour écrire des nombres aléatoires dans une zone de texte multiligne. Comme Brandon et Jon B l'ont noté, vous devez utiliser Invoke () pour sérialiser les appels au thread d'interface graphique.

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

Autres conseils

Une autre option consiste à utiliser une méthode de rappel de thread. C'est une méthode qui existe sur le thread principal, mais lors de la création d'un nouveau thread, vous transmettez un descripteur / une référence à cette méthode. Cela permet au second thread d’appeler la méthode sur le thread principal et à la fonctionnalité de mise à jour / de vérification du champ de texte s’y trouverait.

Recherchez les délégués qui passent entre les threads.

Une option possible consiste à envoyer des messages à un objet de la file d’attente et à utiliser une minuterie dans le formulaire Windows pour lire les messages de cette file d’attente et écrire dans la zone de texte.

Afin de rendre tout bien et threadsage, vous pouvez verrouiller l'objet de la file d'attente lors de la lecture et l'écriture.

Par exemple:

    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’approche la plus sûre consiste à n’avoir qu’un seul thread capable de travailler sur la zone de texte (ou n’importe quel objet de l’interface graphique), et que tout autre thread devant effectuer une action sur la zone de texte communique ses besoins au thread qui contrôle le texte. boîte.

Votre question est donc de savoir comment communiquer entre les threads. Cela dépend de la langue / du système d’exploitation. Vous devez donc fournir davantage d’informations.

Cet article MSDN explique comment passer des appels sécurisés aux threads à les contrôles de formulaire Windows.

Vous ne pouvez accéder aux composants de l'interface graphique qu'à partir du thread principal. Pour écrire dans une zone de texte à partir d'un autre thread, vous devez utiliser BeginInvoke () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top