2014-11-01 164 views
-1

我想将文本写入文本框。为了能够从不同的线程做到这一点,我调用了一个静态方法,它调用一个持有调用和文本框写入的非静态方法。当这样做。我得到的错误,它不能调用,直到设置了窗口句柄,所以我设置它。我的问题是,是的调用循环/崩溃

if (!this.IsHandleCreated) 
    this.CreateHandle(); 
下面

在代码中的位置是唯一的一个,我的程序不会崩溃,但现在它的循环(indefinetly)只有BeginInvoke的代码,但实际上不是文本设置代码如下。我究竟做错了什么?

代码:

private void ActualLog(string input) 
     { 
      var currentForm = form as Main; 

      if (!this.IsHandleCreated) 
       this.CreateHandle(); 
      if (currentForm.txtServerLog.InvokeRequired) 
      { 
       this.BeginInvoke(new Action<string>(ActualLog), new object[] { input }); 
       return; 
      } 
      else 
      { 
       currentForm.txtServerLog.Text += input + "\r\n"; 
       currentForm.txtServerLog.Refresh(); 
      } 
     } 

     public static void Log(string input) 
     { 
      Main main = new Main(); 
      main.ActualLog(input); 
     } 

从我的线程,我会叫Log("Any String");

回答

1

据我所知,你的无限循环是因为,每当txtServerLog已InvokeRequired为真,你调用一个将ActualLog作为动作分配的操作。实质上,每当你进入该条件路径时,你就从ActualLog开始。试想一下,如果你的方法拿出所有的其他代码并开了:

private void ActualLog(string input) 
{ 
     ActualLog(input); 
} 

我会在这里失去了一些皱纹,但我敢肯定,这正是你在这里做什么。鉴于在txtServerLog要求你调用命令的情况下,你永远不会做任何改变状态的事情,你只会永远循环。

你想要做的是将你实际尝试调用的函数分隔成一个单独的日志 - 我假设你的目标是更新文本框。

所以,一个例子:

private void UpdateTextBox(string input) 
{ 
    currentForm.txtServerLog.Text += input + "\r\n"; 
    currentForm.txtServerLog.Refresh(); 
} 

和你ActualLog功能:

private void ActualLog(string input) 
{ 
    var currentForm = form as Main; 

    if (!this.IsHandleCreated) 
    { 
     this.CreateHandle(); 
    } 
    if (currentForm.txtServerLog.InvokeRequired) 
    { 
     this.Invoke(new Action<string>(UpdateTextBox), new object[] { input }); //Make sure to use Invoke, not BeginInvoke 
     return; 
    } 

    UpdateTextBox(input); 
} 

请记住,如果你回到上如果条件以及其他是否-没有一个,没有其他功能的原因,你可以将它们包含在if块之后。

有关您传递的代码的一点 - 您实际上并没有在其中调用Log(),所以我不确定它为什么存在或者它是否与您的问题相关。

+1

@JanH。我不是100%确定你想要做什么,但我已经在上面添加了一个样本。 – furkle 2014-11-01 18:16:14

+0

谢谢!在你的例子中,当使用Invoke而不是BeginInvoke时,它起作用。具有这两个函数的东西只是让我可以从annother Thread中调用Log(),因为Invoke在静态函数中是不允许的(所以我只是把它放在非静态函数中,并从静态函数中调用它)。不过谢谢:) – 2014-11-01 19:44:10

+0

@JanH。啊,我花了更多的时间在WPF上比WinForms,所以我对Invoke/BeginInvoke的区别有点生疏。很高兴听到它的帮助! – furkle 2014-11-01 19:45:08