I want to learn more abou开发者_Go百科t threading and created a little test application that change the backcolor of a label.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//lblColor
public Color theLabel
{
get { return this.lblColor.BackColor; }
set { this.lblColor.BackColor = value; }
}
//btnStart
private void btnStart_Click(object sender, EventArgs e)
{
ThreadTest cColor = new ThreadTest();
Thread tColor = new Thread(new ThreadStart(cColor.ChangeColor));
tColor.Start();
}
}
And...
public class ThreadTest
{
public void ChangeColor()
{
Form1 foo = new Form1();
while (true)
{
foo.theLabel = Color.Aqua;
foo.theLabel = Color.Black;
foo.theLabel = Color.DarkKhaki;
foo.theLabel = Color.Green;
}
}
}
The only problem is why can't i make this code work? I can see that the code in ChangeColor runs but the color of the label don't change.
At first glance, you are constructing a new form
Form1 foo = new Form1();
inside ThreadTest and never displaying the form, my guess is you intended to change the form color on the form with btnStart? You have two options, either pass in the form in to a ParameterizedThreadStart or re-write the code to just operate on the existing form.
Also, based on the code written, you will likely need to use Invoke to update the state of the form as you cannot have worker threads update the UI. I will tweak your code and posted a revised example if someone doesn't beat me to it.
Edit
In this case you don't need the invoke... but here is what I think you were intending...
private void btnStart_Click(object sender, EventArgs e)
{
ThreadTest cColor = new ThreadTest();
Thread tColor = new Thread(new ParameterizedThreadStart(cColor.ChangeColor));
tColor.Start(this);
}
public class ThreadTest
{
public void ChangeColor(Object state)
{
Form1 foo = (Form1) state;
while (true)
{
foo.theLabel = Color.Aqua;
foo.theLabel = Color.Black;
foo.theLabel = Color.DarkKhaki;
foo.theLabel = Color.Green;
}
}
}
Also, it is important to set worker threads as background threads, otherwise when you close the form, the thread will keep that appliaction open.
tColor.IsBackground = true;
Additional Example
A slightly different example would be to have multiple threads trying to update the same value and see how they are interleaved... simple snippet to get the ball rolling.
private void btnStart_Click(object sender, EventArgs e)
{
CreateBackgroundColorSetter(Color.Aqua);
CreateBackgroundColorSetter(Color.Black);
CreateBackgroundColorSetter(Color.DarkKhaki);
CreateBackgroundColorSetter(Color.Green);
}
private void CreateBackgroundColorSetter(Color color)
{
var thread = new Thread(() =>
{
while (true)
{
theLabel = color;
Thread.Sleep(100);
}
});
thread.IsBackground = true;
thread.Start();
}
you have 2 issues
a) you are not supposed to update the UI from other threads
b) even if you were allowed to do it you need to tell the UI to repaint
These are non trivial issues
If you are just experimenting with threading then use Debug.WriteLine to see what the background threads are doing
If you actually need to update the UI in the background then lookup BeginInvoke and InvokeNeeded
If you really need to do threading in a GUI app you are going to need BackgroundWorker or something like it. As noted, other threads cannot update the GUI anyway so the sample shown there is a better model for moving long-running work items out of your main thread.
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.
If you want do experiments with threading just create a console application and google "threading tutorial c#" to get some example.
Regarding threading and winform you can have a look at the below link just to have an idea about the consideration you should make before access win form property from another thread
In WinForms, why can't you update UI controls from other threads?
精彩评论