[英]About Multithreading with GUIs in c#
我正在阅读要发布的示例,但我不明白的是:他们说,如果我想与GUI进行交互,则必须由UI线程完成。 。调用Controll类的方法。 在示例中,我不明白为什么我们要在GenerateRandomCharacters
方法中使用output.Invoke...
在该方法中更改输出,但是在Toggle()
中也要更改输出(颜色),则没有.Invoke
? 是不是一样?
public class RandomLetters
{
private static Random generator = new Random(); // for random letters
private bool suspended = false; // true if thread is suspended
private Label output; // Label to display output
private string threadName; // name of the current thread
// RandomLetters constructor
public RandomLetters( Label label )
{
output = label;
} // end RandomLetters constructor
// delegate that allows method DisplayCharacter to be called
// in the thread that creates and maintains the GUI
private delegate void DisplayDelegate( char displayChar );
// method DisplayCharacter sets the Label's Text property
private void DisplayCharacter( char displayChar )
{
// output character in Label
output.Text = threadName + ": " + displayChar;
} // end method DisplayCharacter
// place random characters in GUI
public void GenerateRandomCharacters()
{
// get name of executing thread
threadName = Thread.CurrentThread.Name;
while ( true ) // infinite loop; will be terminated from outside
{
// sleep for up to 1 second
Thread.Sleep( generator.Next( 1001 ) );
lock ( this ) // obtain lock
{
while ( suspended ) // loop until not suspended
{
Monitor.Wait( this ); // suspend thread execution
} // end while
} // end lock
// select random uppercase letter
char displayChar = ( char ) ( generator.Next( 26 ) + 65 );
// display character on corresponding Label
output.Invoke( new DisplayDelegate( DisplayCharacter ),
new object[] { displayChar } );
} // end while
} // end method GenerateRandomCharacters
// change the suspended/running state
public void Toggle()
{
suspended = !suspended; // toggle bool controlling state
// change label color on suspend/resume
output.BackColor = suspended ? Color.Red : Color.LightGreen;
lock ( this ) // obtain lock
{
if ( !suspended ) // if thread resumed
Monitor.Pulse( this );
} // end lock
} // end method Toggle
} // end class RandsomLetters
编辑:这是实际的电话:
public partial class GUIThreadsForm : Form
{
public GUIThreadsForm()
{
InitializeComponent();
} // end constructor
private RandomLetters letter1; // first RandomLetters object
private RandomLetters letter2; // second RandomLetters object
private RandomLetters letter3; // third RandomLetters object
private void GUIThreadsForm_Load( object sender, EventArgs e )
{
// create first thread
letter1 = new RandomLetters( thread1Label );
Thread firstThread = new Thread(
new ThreadStart( letter1.GenerateRandomCharacters ) );
firstThread.Name = "Thread 1";
firstThread.Start();
continues...
这是调用Toggle()方法的方式:
private void threadCheckBox_CheckedChanged( object sender, EventArgs e )
{
if ( sender == thread1CheckBox )
letter1.Toggle();
else if ( sender == thread2CheckBox )
letter2.Toggle();
else if ( sender == thread3CheckBox )
letter3.Toggle();
} // end method threadCheckBox_CheckedChanged
在CheckedChanged事件中激活复选框控件后,它进入Toggle()方法
大概是什么在调用此类的方法,只是从非UI线程调用GenerateRandomCharacters
从UI线程仅调用Toggle
,因此为什么只有GenerateRandomCharacters
需要显式编组到UI线程。
您将需要查看如何调用这些方法来进行验证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.