2014-11-01 122 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