12 Replies - 6819 Views - Last Post: 01 December 2010 - 10:31 AM Rate Topic: -----

#1 questuk   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 30-November 10

How to return Variable from a different thread?

Posted 30 November 2010 - 12:46 PM

Hi,

I have been trying for days to get this working and searched across the internet, I keep seeing people asking the same question but cannot see an answer that someone new to C# can understand.

I have a textbox on the Main UI thread. I have data (variable = RXstring)coming in on another thread (actually the serialport).

I need to get the variable somehow back to the Main UI thread. Because in this thread i compare the data received.


For example:

If RXstring == ("123") then output to the textbox, if not ignore data and wait for correct data.


From what I have read and am now totally confused i think its something to do with delegate?

Bear in mind I am new at C# so ideally comments on what each line does would be very helpful.

I am also looking for a helpful and friendly forum :rolleyes:

Regards

Gary

Is This A Good Question/Topic? 0
  • +

Replies To: How to return Variable from a different thread?

#2 JackOfAllTrades   User is offline

  • Saucy!
  • member icon

Reputation: 6259
  • View blog
  • Posts: 24,028
  • Joined: 23-August 08

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 01:03 PM

Perhaps this tutorial might be helpful. Also, whenever I deal with threads in C#, the first place I look is this helpful e-book.
Was This Post Helpful? 0
  • +
  • -

#3 mavarazo   User is offline

  • D.I.C Head
  • member icon

Reputation: 37
  • View blog
  • Posts: 182
  • Joined: 25-October 10

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 01:06 PM

You find many examples with google:

http://www.google.co...9ImCZ4A&cad=rja

Or you have to give us more infos to help you more.
Do you have the thread outside of the UI? BackgroundWorker, Thread or Threadpool?
Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 02:10 PM

Principal #1: You are not supposed to access GUI elements directly across threads. If you keep looking for ways to do it, then that is why you are not finding any.

Principal #2: Black box programming. If you were to cobble together a way to violate rule #1 then you are tightly binding the two classes/forms/threads so that they are dependant on each other and that a change in one can break the other. You might as well just make them one object/thread/class/form. You are *supposed* to be making lots of little black boxes of code that know as little as possible about each other. The box does its job and that's it. One box of code is not supposed to do things at a low level inside another box.

You need to accept that one thread is not supposed to directly change the text property of the form. Instead it is supposed to raise an event saying "I'm done" or "25%" or "Fred". Any other class subscribing to that event in that class can then react as it needs to.


Quick and easy custom events
Bulding an application - Part 1
Building an application - Part 2


Think of bingo parlor. You are trying to make your class not only pick the ball, but then go around and check each player's card. Instead, you need to yell out the number, and let each player check their own card. This way the ball caller is one black box that raises the YellNumber("B-14") event, and each player is a subscriber that reacts as needed.
Was This Post Helpful? 0
  • +
  • -

#5 questuk   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 30-November 10

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 02:19 PM

Quote

Or you have to give us more infos to help you more.
Do you have the thread outside of the UI? BackgroundWorker, Thread or Threadpool?


Hi Mavarazo

It is essential that the string is available in the main thread as I access it with extra data from the Main thread.
As I mentioned earlier, I compare the returned data from the serial port in the Main thread.


Can you please help me to find a solution. I will need some explanation as to what each line does, as I have seen many replies
to this type of question, but they are far too technical, I always learn best by getting working code then studying it to see how it actually works.



Regards Gary



private void serialPort1_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
    {
      this.Invoke((MethodInvoker)delegate
      {
        RxString = serialPort1.ReadExisting();
      });

      Update_textBox1();    // **** FAILS HERE **** 
                            // (Update_textBox1 IS in my Main thread and uses RxString)
                            
                            // System.InvalidOperationException was unhandled
                            // Message="Cross-thread operation not valid: Control
                            // 'textBox1' accessed from a thread other than the 
                            // thread it was created on."
   

    }


Was This Post Helpful? 0
  • +
  • -

#6 questuk   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 30-November 10

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 02:35 PM

Hi tlhIn'toq,

Thanks for your post, yes i do realise that one thread is not supposed to directly change the text property of the form and when i program i always like to have code that does its job then returns back to Main with a result or task completed.

As you say I am trying to get "Black Boxes", the rest of my code is like that.

I have seen many examples where they simply update a textbox from a seperate thread to Main, but as I want to compare received data etc, it seems wrong if this isn't done in the Main thread? Along with all my other code.

I will look at the links you gave. But I have read so many pages of code trying to find the answer, and am a bit confused at the moment. As i mentioned in another reply, I always learn from a working example and then study it to see how it works.

Thanks

Regards

Gary

Hi JackOfAllTrades,

Thanks for the links although I have already looked at the ebook link before and found it hard to understand.

I tried the other link but I couldn't get it to run.

But I will study it more.

Thanks

Regards

Gary
Was This Post Helpful? 0
  • +
  • -

#7 mavarazo   User is offline

  • D.I.C Head
  • member icon

Reputation: 37
  • View blog
  • Posts: 182
  • Joined: 25-October 10

Re: How to return Variable from a different thread?

Posted 30 November 2010 - 11:46 PM

So you have produce the thread in the same class as you try to access the variable??

Quote

It is essential that the string is available in the main thread as I access it with extra data from the Main thread.

Was This Post Helpful? 0
  • +
  • -

#8 questuk   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 30-November 10

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 01:09 AM

Quote

So you have produce the thread in the same class as you try to access the variable??


Hi

I have added my code below, (its a cut down version for clarity on here, and have had to edit at work and I don't have the software to run it there, but don't think I've taken out anything essential?)

How do I know which thread I am in, thats what confuses me, I know serial port runs on a background thread.

As soon as I have an idea what I am doing wrong, I will then go back and read my C# book again. Would be great if you could assist me so that i can do this.

Regards

Gary

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

namespace GB_Application
{

    public partial class Form1 : Form
    {
        public string RxString = " RxString = Data from RS232 ...";

        public Form1()
        {
            InitializeComponent();      
            Update_textBox1();
            serialPort1.Open();
        }        

        private void Update_textBox1()                          
        {
            textBox1.AppendText(RxString + "\r\n");         
        }  

        public void serialPort1_DataReceived(object sender,
            System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            this.Invoke((MethodInvoker)delegate             
            {
                RxString = serialPort1.ReadExisting();
            });

            Update_textBox1();                    // **** FAILS HERE ****
                                                        
        }
    }
}


Was This Post Helpful? 0
  • +
  • -

#9 Adkins   User is offline

  • D.I.C Addict
  • member icon

Reputation: 66
  • View blog
  • Posts: 560
  • Joined: 27-October 09

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 01:45 AM

I would say the way to go about this would be to write a method whose only job is to check if the value received is the one you want. If it is then release the value to the GUI thread, and the GUI thread is then simply writing whatever value it gets without checking.
Was This Post Helpful? 0
  • +
  • -

#10 mavarazo   User is offline

  • D.I.C Head
  • member icon

Reputation: 37
  • View blog
  • Posts: 182
  • Joined: 25-October 10

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 02:26 AM

I dont think, that your code will ever work :).

That code below shows how it works, but I don't know your archtecture, so I just can guess.

FormMain:
namespace Example {
	public partial class FormMain : Form {
		private SerialPortClass _serialPort 1;

		public FormMain() {
			_serialPort1 = new SerialPortClass();
		}
		
		private SerialPort_DataReceived(string s) {
			if (this.InvokeRequired) {
                this.BeginInvoke((MethodInvoker)delegate {
                    SerialPort_DataReceived(s);
                });
                return;
            }
			
			textBox1.AppendText(s + Environment.NewLine);
		}
	}
}



SerialPortClass
namespace Example {
	public delegate void DataReceivedDelegate(string p);

	public class SerialPortClass {
		public event DataReceivedDelegate Received;
		
		public SerialPortClass() {
			Received = "Hello i am a test";
		}
		
		public String DataReceived {
			set {
                if (Received != null)
                    Received(value);
            }
		}
	}
}


Was This Post Helpful? 0
  • +
  • -

#11 questuk   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 30-November 10

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 06:18 AM

Hi Mavarazo,

I have put your code into a new project to examine it, but it fails on one line (i have commented it) I have attached the whole project so its easier for you.

Thanks for all your help so far.

Regards

Gary

Attached File(s)

  • Attached File  test9.zip (16.42K)
    Number of downloads: 119

Was This Post Helpful? 0
  • +
  • -

#12 mavarazo   User is offline

  • D.I.C Head
  • member icon

Reputation: 37
  • View blog
  • Posts: 182
  • Joined: 25-October 10

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 06:31 AM

Sorry, I used the Forumeditor to code :), but it's a beginner failure.

private void SerialPort_DataReceived(string s) {
	if (this.InvokeRequired) {
		this.BeginInvoke((MethodInvoker)delegate {
     	                 	  SerialPort_DataReceived(s);
	   });
	   return;
	}
	textBox1.AppendText(s + Environment.NewLine);
}


This post has been edited by mavarazo: 01 December 2010 - 06:32 AM

Was This Post Helpful? 0
  • +
  • -

#13 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: How to return Variable from a different thread?

Posted 01 December 2010 - 10:31 AM

SerialPortClass should raise an event with the string S as it's event argument.
Your form class should subscribe to that event. It will then receive the string as the arguments of the event and do whatever it is meant to do with that string: Which can include setting a form property for use throughout the form.

But you seem hellbent on trying to force direct change of the GUI elements across threads despite being told that's not how to do and despite all the Visual Studio errors telling you that's not the way to do it.

I'll be unsubscribing from this thread now. Some people just won't take advice.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1