deleyd
asked on
How does the delegate know which thread to run the method on?
The following sample program creates a form with a textbox and a button.
When the button is pressed, it writes "Written by the main thread" to the textbox
starts a second thread,
the second thread waits 2 seconds, then writes "Written by the background thread" to the textbox via:
line 50: string text = "Written by the background thread.";
line 56: SetTextCallback d = new SetTextCallback(SetText);
line 57: this.Invoke (d, new object[] { text + " (Invoke)" });
Questions:
1. How does the delegate know which thread to run the SetText method on?
2. on line 57, Is the new object[] part necessary?
When the button is pressed, it writes "Written by the main thread" to the textbox
starts a second thread,
the second thread waits 2 seconds, then writes "Written by the background thread" to the textbox via:
line 50: string text = "Written by the background thread.";
line 56: SetTextCallback d = new SetTextCallback(SetText);
line 57: this.Invoke (d, new object[] { text + " (Invoke)" });
Questions:
1. How does the delegate know which thread to run the SetText method on?
2. on line 57, Is the new object[] part necessary?
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace CrossThreadDemo
{
public class Form1 : Form
{
// This delegate enables asynchronous calls for setting
// the text property on a TextBox control.
delegate void SetTextCallback(string text);
// This thread is used to demonstrate thread-safe way
// to call a Windows Forms control.
private Thread demoThread = null;
private TextBox textBox1;
private Button setTextSafeBtn;
public Form1()
{
InitializeComponent();
}
// This event handler creates a thread that calls a
// Windows Forms control in a thread-safe way.
private void setTextSafeBtn_Click(
object sender,
EventArgs e)
{
// Create a background thread and start it.
this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.demoThread.Start();
// Continue in the main thread. Set a textbox value
// that will be overwritten by demoThread.
textBox1.Text = "Written by the main thread.";
}
// If the calling thread is different from the thread that
// created the TextBox control, this method passes in the
// the SetText method to the SetTextCallback delegate and
// passes in the delegate to the Invoke method.
private void ThreadProcSafe()
{
// Wait two seconds to simulate some background work
// being done.
Thread.Sleep(2000);
string text = "Written by the background thread.";
// Check if this method is running on a different thread
// than the thread that created the control.
if (this.textBox1.InvokeRequired)
{
// It's on a different thread, so use Invoke.
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke (d, new object[] { text + " (Invoke)" });
}
else
{
// It's on the same thread, no need for Invoke
this.textBox1.Text = text + " (No Invoke)";
}
}
// This method is passed in to the SetTextCallBack delegate
// to set the Text property of textBox1.
private void SetText(string text)
{
this.textBox1.Text = text;
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.setTextSafeBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(12, 12);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(360, 20);
this.textBox1.TabIndex = 0;
//
// setTextSafeBtn
//
this.setTextSafeBtn.Location = new System.Drawing.Point(96, 55);
this.setTextSafeBtn.Name = "setTextSafeBtn";
this.setTextSafeBtn.TabIndex = 2;
this.setTextSafeBtn.Text = "Safe Call";
this.setTextSafeBtn.Click += new System.EventHandler(this.setTextSafeBtn_Click);
//
// Form1
//
this.ClientSize = new System.Drawing.Size(388, 96);
this.Controls.Add(this.setTextSafeBtn);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Super. I'm going to follow-up with another question which I'll start a new post and add comment here pointing to it.
ASKER
ASKER
Why does it still work if I remove the new object[] part and just pass text? Why is this bad to do?
Open in new window
It seems to compile and run without complaint.