Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Control.InvokeRequired-受竞争条件约束_C#_Multithreading_Cross Thread - Fatal编程技术网

C# Control.InvokeRequired-受竞争条件约束

C# Control.InvokeRequired-受竞争条件约束,c#,multithreading,cross-thread,C#,Multithreading,Cross Thread,我在另一篇文章中找到了一个解决跨线程异常问题的建议解决方案,并在下面的代码中使用了它,但我发现它充其量是不稳定的。我的测试表明,它的正确运行取决于比赛条件,因此我希望有人能够指出明显的问题,或者提供更可靠的解决方案 我有一个包含两个简单表单的程序,其中Form1的唯一目的是打开Form2。Form2只包含一个RichTextBox,其代码启动一个线程,该线程以任意方式访问该RichTextBox。当执行到达InvokeRequired属性时,它通常(但不总是)为false,因此它直接进入Rich

我在另一篇文章中找到了一个解决跨线程异常问题的建议解决方案,并在下面的代码中使用了它,但我发现它充其量是不稳定的。我的测试表明,它的正确运行取决于比赛条件,因此我希望有人能够指出明显的问题,或者提供更可靠的解决方案

我有一个包含两个简单表单的程序,其中Form1的唯一目的是打开Form2。Form2只包含一个RichTextBox,其代码启动一个线程,该线程以任意方式访问该RichTextBox。当执行到达InvokeRequired属性时,它通常(但不总是)为false,因此它直接进入RichTextBox访问,在那里生成跨线程异常。然而,当我在测试invokererequired属性之前调用Thread.Sleep(…)时,它似乎工作正常。然而,我不喜欢用睡眠来达到这个目的,因为它看起来像一个可能并不总是有效的障碍。有没有可靠但合理的方法来进行跨线程通信?谢谢

public partial class Form1 : Form
{
   public Form1()
   {
      InitializeComponent();
      var form2 = new Form2();
      form2.ShowDialog();
   }
}

public partial class Form2 : Form
{
   public Form2()
   {
      InitializeComponent();
      Thread myThread = new Thread(new ThreadStart(myStartingMethod));
      myThread.Start();
   }

   void myStartingMethod()
   {
      Test("Hello world!\n");
   }

   private delegate void myCallback(string text);
   private void Test(string text)
   {
      // If I put Thread.Sleep(...something...) here it works better.
      if (myRichTextBox.InvokeRequired)
      {
         myCallback d = new myCallback(Test);
         Invoke(d, new Object[] { text });
      }
      else
      {
         // Cross-thread exception usually occurs, but not always.
         int x = myRichTextBox.TextLength;
      }
   }
}

这是一种常见的模式,并且已经证明是有效的。这里的问题不是模式,而是如何使用它。好吧,这是因为控件句柄尚未创建,所以不能(如果它是单个表单),也不能
Invoke
工作。您的
Sleep
显然要等待足够长的时间才能创建句柄,然后它才能工作。与其使用构造函数,不如尝试使用另一个事件(不确定,
显示了
可能?)来测试另一个线程。是的,这是一场不可避免的竞赛。如果您需要它,因为您不知道代码在哪个线程上运行,那么您就会遇到大问题,很难证明这样的代码始终是线程安全的。但话说回来,你总是知道的。不要用它。并始终确保在工作线程完成之前不允许关闭窗体。