How To Do Multithreading And Cross Threading in C# : Template

I wrote this as an example piece for cross-threading operations which allows you to send values to and from non gui threads. It is very well commented and explained, so I will keep the introduction to this piece simple.

Controls and names@
TB1 As TextBox
TB2 As TextBox
listBox1 As ListBox
Button4 As Button
Variable Setters@

// Updates the textbox1 text.
 private void UpdateTextB1(string text) //This is the method the callback will work with for TB1.
 {
 // Set the textbox1 text.
 TB1.Text = text;
 }
 // Updates the textbox2 text.
 private void UpdateTextB2(string text) //This is the method the callback will work with for TB2.
 {
 // Set the textbox text.
 TB2.Text = text;
 }
 // Updates the listbox item.
 private void UpdateLB(string text, string text2) //This is the method the callback will work with for ListBox1.
 {
 // Set the listbox item.
 listBox1.Items.Add(text + " " + text2);
 }

Button4 Code@

private void button4_Click(object sender, EventArgs e)
 {
 //At this section we will declare a new thread and provide it with its two parameters. i1 and i2,
 //because that is what is required by the NonUIThread void. (You'll see this further down.)
 var UodateThread = new Thread(() => NonUIThread(i1, i2)); //Pass the variables to the method.
 bgw.RunWorkerAsync(); UodateThread.Start(); //We are simply running both the background worker and
 //the non UI thread.
 }

Background Worker Do Work Event@

private void bgw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
 {
 //So we want to access TB1 but its on another thread, (the thread it was probably created on)
 //To do this, we will need a delegate called UpdateTextB1Callback, and it requires a method.
 //The method we will be using is UpdateTextB1, and it takes one parameter.
 TB1.Invoke(new UpdateTextB1Callback(UpdateTextB1),
 new string[] { "Text sent on non-UI BG Worker with no variables." });
 //Since we know that the control is on another thread and we can't access it, we don't need to
 //check with an if statement if the control needs invoking, so we will just invoke it, since we
 //know it needs invoking, and checking is not required anyway. I've provided the commented code below
 //for reference purposes... to check if a control needs updating, just use TB1 as control example
 //and do:
 //if (TB1.InvokeRequired)
 //{
 // TB1.Invoke(:action:);
 // //If you uncomment this statement, you will find an error in the code where action is.
 // //This is where you must insinuate your own action for that invoke method. Below are two examples.
 //}
 //else { } //The control doesn't need invoking, do as you please.
 }

Non UI Thread and summery comments@

private void NonUIThread(string a, string B )
 {
 TB2.Invoke(new UpdateTextB2Callback(UpdateTextB2),
 new object[] { "Text sent on non-UI thread with variables. "
 + a + " from string i1. And a value of " + b + " from string i2" });
 //I would like to point out two things, between these two. The one above is a non-safe method
 //because it used an object which is a base type. In codeology, anything can be an object, so it
 //can be manipulated. The one below is not exactly the best way to do this either, but its one of
 //the most practiced and preferred among some developers, as it does exactly as intended, and its
 //the easiest way to pass information between different threads.
 listBox1.Invoke(new UpdateLBCallback(UpdateLB),
 new string[] { "New", "List Item" });
 //Conclusion... You might be wondering how the last bit on line 91, 92 works. But just look at the
 //code and you can see how it works, and what the delegate is doing with the method to pass the values.
 //I didn't write this as a tutorial. But I just felt like some of it needed commenting for clarity. :)/>/>/>/>/>
 //Further to draw a close and some things to try. If you know what your threads are doing and how they
 //are accessing your data, then you can use (this NON recommended bool) to skip cross threading issues.
 //CheckForIllegalCrossThreadCalls = false; will allow your application to interact without the need
 //for the above methods and multi-threading or cross-threading methods. Again, this is not something
 //I advocate using, as it can cause monstrous problems on big applications responsible for handing data etc.
 //Put at the top of the void "CheckForIllegalCrossThreadCalls = false;" in place of this (Without COMMENTS //):
 //TB2.Invoke(new UpdateTextB2Callback(UpdateTextB2),
 // new object[] { "Text sent on non-UI thread with variables. "
 // + a + " from string i1. And a value of " + b + " from string i2" });
 //And above it, put //CheckForIllegalCrossThreadCalls = false; at the top of the void (inside).
 //Now execute and you will find you are able to access your controls without restrictions, and this
 //is because of the bool we used at the top of the method. I hope this helps some people out there,
 //as you could use this as a template to cross-threading and passing values to different threads.
 }

Tested and working perfectly on .Net Framework 4.5.2. Class as it stands is an example piece which can be used as a template for cross threading scenarios@

 //Lets define our delegates below
 public delegate void UpdateTextB1Callback(string text); //For TextBox1 named TB1.
 public delegate void UpdateTextB2Callback(string text); //For TextBox2 named TB2.
 public delegate void UpdateLBCallback(string string1, string string2); //For ListBox1 named ListBox1.
 //Declare two variables, we can use these to pass them between threads.
 private string i1 = "String A"; private string i2 = "String B";
 // Updates the textbox1 text.
 private void UpdateTextB1(string text) //This is the method the callback will work with for TB1.
 {
 // Set the textbox1 text.
 TB1.Text = text;
 }
 // Updates the textbox2 text.
 private void UpdateTextB2(string text) //This is the method the callback will work with for TB2.
 {
 // Set the textbox text.
 TB2.Text = text;
 }
 // Updates the listbox item.
 private void UpdateLB(string text, string text2) //This is the method the callback will work with for ListBox1.
 {
 // Set the listbox item.
 listBox1.Items.Add(text + " " + text2);
 }
 private void button4_Click(object sender, EventArgs e)
 {
 //At this section we will declare a new thread and provide it with its two parameters. i1 and i2,
 //because that is what is required by the NonUIThread void. (You'll see this further down.)
 var UodateThread = new Thread(() => NonUIThread(i1, i2)); //Pass the variables to the method.
 bgw.RunWorkerAsync(); UodateThread.Start(); //We are simply running both the background worker and
 //the non UI thread.
 }
 private void bgw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
 {
 //So we want to access TB1 but its on another thread, (the thread it was probably created on)
 //To do this, we will need a delegate called UpdateTextB1Callback, and it requires a method.
 //The method we will be using is UpdateTextB1, and it takes one parameter.
 TB1.Invoke(new UpdateTextB1Callback(UpdateTextB1),
 new string[] { "Text sent on non-UI BG Worker with no variables." });
 //Since we know that the control is on another thread and we can't access it, we don't need to
 //check with an if statement if the control needs invoking, so we will just invoke it, since we
 //know it needs invoking, and checking is not required anyway. I've provided the commented code below
 //for reference purposes... to check if a control needs updating, just use TB1 as control example
 //and do:
 //if (TB1.InvokeRequired)
 //{
 // TB1.Invoke(:action:);
 // //If you uncomment this statement, you will find an error in the code where action is.
 // //This is where you must insinuate your own action for that invoke method. Below are two examples.
 //}
 //else { } //The control doesn't need invoking, do as you please.
 }
 private void NonUIThread(string a, string B )
 {
 TB2.Invoke(new UpdateTextB2Callback(UpdateTextB2),
 new object[] { "Text sent on non-UI thread with variables. "
 + a + " from string i1. And a value of " + b + " from string i2" });
 //I would like to point out two things, between these two. The one above is a non-safe method
 //because it used an object which is a base type. In codeology, anything can be an object, so it
 //can be manipulated. The one below is not exactly the best way to do this either, but its one of
 //the most practiced and preferred among some developers, as it does exactly as intended, and its
 //the easiest way to pass information between different threads.
 listBox1.Invoke(new UpdateLBCallback(UpdateLB),
 new string[] { "New ", "List Item" });
 //Conclusion... You might be wondering how the last bit on line 91, 92 works. But just look at the
 //code and you can see how it works, and what the delegate is doing with the method to pass the values.
 //I didn't write this as a tutorial. But I just felt like some of it needed commenting for clarity. :)/>/>/>/>/>
 //Further to draw a close and some things to try. If you know what your threads are doing and how they
 //are accessing your data, then you can use (this NON recommended bool) to skip cross threading issues.
 //CheckForIllegalCrossThreadCalls = false; will allow your application to interact without the need
 //for the above methods and multi-threading or cross-threading methods. Again, this is not something
 //I advocate using, as it can cause monstrous problems on big applications responsible for handing data etc.
 //Put at the top of the void "CheckForIllegalCrossThreadCalls = false;" in place of this (Without COMMENTS //):
 //TB2.Invoke(new UpdateTextB2Callback(UpdateTextB2),
 // new object[] { "Text sent on non-UI thread with variables. "
 // + a + " from string i1. And a value of " + b + " from string i2" });
 //And above it, put //CheckForIllegalCrossThreadCalls = false; at the top of the void (inside).
 //Now execute and you will find you are able to access your controls without restrictions, and this
 //is because of the bool we used at the top of the method. I hope this helps some people out there,
 //as you could use this as a template to cross-threading and passing values to different threads.
 }
 #endregion Multithreading
 }
}