【问题标题】:About Multithreading with GUIs in c#关于 C# 中的 GUI 多线程
【发布时间】:2014-01-30 21:23:08
【问题描述】:

我正在阅读我将要发布的示例,但我不明白的是: 他们说,如果我想与 GUI 进行交互,它必须由 UI 线程完成。换句话说:使用 Controll 类的 .Invoke 方法。在示例中,我不明白为什么我们在更改输出的GenerateRandomCharacters 方法中使用output.Invoke...,但在更改输出(颜色)的Toggle() 中没有@987654324 @?不一样吗?

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() 方法后

【问题讨论】:

  • "无限循环;将从外部终止" 你不会打电话给Thread.Abort,不是吗?!这很危险。
  • @usr 不,我不是。有一个 CheckBox 控件,检查后线程必须被挂起。
  • 我可以建议改一下问题的标题吗?

标签: c# multithreading invoke


【解决方案1】:

大概调用这个类的方法只是从非 UI 线程调用 GenerateRandomCharacters,而 Toggle 只是从 UI 线程调用,因此为什么只有 GenerateRandomCharacters 需要显式编组到界面线程。

您需要查看如何调用这些方法来验证这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2011-06-24
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    相关资源
    最近更新 更多