K
kndg
Hi all,
When I first learn threading, I had always been advised that doing a
cross-thread operation on a GUI thread is not safe and should be
avoided. But it is not until recently that it makes me wonder why that
is bad. Quick googling directs me to STA and COM which I have no idea
about. But, if it really that bad, why it is not enforced (during
runtime)? For example, I was unable to make below code to throw the
exception.
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace MyNamespace
{
public class MyForm : Form
{
private Label label1;
private Button button1;
public MyForm()
{
InitializeComponent();
}
void InitializeComponent()
{
label1 = new Label();
label1.Location = new Point(10, 10);
label1.Size = new Size(200, 20);
button1 = new Button();
button1.Location = new Point(10, 30);
button1.Text = "Start";
button1.Click += button1_Click;
Controls.Add(label1);
Controls.Add(button1);
}
void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
new Thread(SimulateLongRunningWork).Start();
}
void SimulateLongRunningWork()
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100); // simulate long running task
label1.Text = "Progress: " + i + "%"; // <- cross-thread operation
}
label1.Text += " Completed!"; // <- cross-thread operation
button1.Text = "Completed"; // <- cross-thread operation
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MyForm());
}
}
}
Yes, it will throw exception when running inside IDE/debugger, but if I
run it alone, it will just run - no exception thrown. This is contrast
to WPF which always throws exception (with/without debugger).
Does anyone have any idea why?
When I first learn threading, I had always been advised that doing a
cross-thread operation on a GUI thread is not safe and should be
avoided. But it is not until recently that it makes me wonder why that
is bad. Quick googling directs me to STA and COM which I have no idea
about. But, if it really that bad, why it is not enforced (during
runtime)? For example, I was unable to make below code to throw the
exception.
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace MyNamespace
{
public class MyForm : Form
{
private Label label1;
private Button button1;
public MyForm()
{
InitializeComponent();
}
void InitializeComponent()
{
label1 = new Label();
label1.Location = new Point(10, 10);
label1.Size = new Size(200, 20);
button1 = new Button();
button1.Location = new Point(10, 30);
button1.Text = "Start";
button1.Click += button1_Click;
Controls.Add(label1);
Controls.Add(button1);
}
void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
new Thread(SimulateLongRunningWork).Start();
}
void SimulateLongRunningWork()
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100); // simulate long running task
label1.Text = "Progress: " + i + "%"; // <- cross-thread operation
}
label1.Text += " Completed!"; // <- cross-thread operation
button1.Text = "Completed"; // <- cross-thread operation
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MyForm());
}
}
}
Yes, it will throw exception when running inside IDE/debugger, but if I
run it alone, it will just run - no exception thrown. This is contrast
to WPF which always throws exception (with/without debugger).
Does anyone have any idea why?