1

I want to run an own class in another thread, but if I do that I can't use my, for example, labels inside of an EventHandler, how can I avoid that?

That's how my code looks:

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

namespace Ts3_Movearound
{
    public partial class Form1 : Form
    {
        TS3_Connector conn = new TS3_Connector();
        Thread workerThread = null;
        public Form1()
        {
            InitializeComponent();
            conn.runningHandle += new EventHandler(started);
            conn.stoppedHandle += new EventHandler(stopped);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //System.Threading.Thread connw = new System.Threading.Thread(conn);
            workerThread = new Thread(conn.Main);
            workerThread.Start();
        }

        public void started(Object sender, EventArgs e)
        {
            label1.Text = "Status: Running!";
        }
        public void stopped(Object sender, EventArgs e)
        {
            label1.Text = "Status: Stopped!";
        }
    }
}

And that's the error:

InvalidOperationExpetion in Line "label1.Text = "Status: Running!";"

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Styler2go
  • 604
  • 2
  • 12
  • 32

3 Answers3

5

You can only update the control via the UI thread. Use label1.Invoke() to do that:

label1.Invoke((MethodInvoker)delegate {
    label1.Text = "Status: Running!";"
});
alexn
  • 57,867
  • 14
  • 111
  • 145
1

I would look at using a BackgroundWorker for this. You then use the following:

1) Before you call RunWorkerAsync you set the label to running as there are no thread issues. 2) After calling RunWorkerAsync if you set any control use:

            label1.Invoke(new Action(() => label1.Text = @"Status: Running!"));

3) Once the process has finished you can then set the label to stopped by assigning a method to the RunWorkerCompleted event. There should be no thread issues in this method as it runs on the main thread.

InContext
  • 2,461
  • 12
  • 24
0

SO has a lot of data about it. I've found some for you:

Can you access UI elements from another thread? (get not set)

How do I access GUI-Elements in another thread?

How to directly access the UI thread from the BackgroundWorker thread in WPF?

Community
  • 1
  • 1
Azodious
  • 13,752
  • 1
  • 36
  • 71