2012-07-27 62 views
-2

我想要在文本框中異步顯示內容?有誰知道我的代碼在下面列出的錯誤?我想實現文本框中的文本會每秒更新一次新值?我也想問爲什麼每次在調用控制器的invoke方法之前檢查InvokeRequired?異步文本框中的內容

 private void Counting(int Num) 
    { 

     int i = 0; 
     string counter = null; 
     while (i < Num) 
     { 
      Thread.Sleep(1000); 
      counter = string.Format(" {0}", i); 
      tbxStatus.BeginInvoke(new UpdateStatusDelegate(UpdateStatus), new string[] { counter }); 
     } 

    } 

    public void UpdateStatus(string data) 
    { 
     tbxStatus.Text += data; 
    } 

    public delegate void UpdateStatusDelegate(string data); 

    public delegate void CountDelegate(int num); 

    private void btnStart_Click(object sender, EventArgs e) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new CountDelegate(Counting), new object[] { 5 }); 
     } 
     else 
      Counting(5); 
    } 

感謝

回答

1

InvokeRequired測試應該是代表裏面:

public void UpdateStatus(string data) 
{ 
    if (this.tbxStatus.InvokeRequired) 
    { 
     UpdateStatusDelegate d = new UpdateStatusDelegate(UpdateStatus); 
     this.Invoke(d, new object[] { data }); 
    } 
    else 
    { 
     this.tbxStatus.Text = data; 
    } 
} 

您也可以使這是一個極大的方便,如果您使用下面的擴展方法清潔尋找:

public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke 
{ 
    if (isi.InvokeRequired) { 
     IAsyncResult result = isi.BeginInvoke(call, new object[] { isi }); 
     object endResult = isi.EndInvoke(result); return (TResult)endResult; 
    } 
    else 
     return call(isi); 
} 

public static void SafeInvoke(this T isi, Action call) where T : ISynchronizeInvoke 
{ 
    if (isi.InvokeRequired) isi.BeginInvoke(call, new object[] { isi }); 
    else 
     call(isi); 
} 

所以,如果我想調用一個我已經定義的方法我的UI線程(就像在你的表單實例中定義的方法),你可以用下面的代碼這樣做(而不需要創建任何委託或任何東西):

formInstance.SafeInvoke(f => f.myFormMethod("parameter1","parameter2")); 
你的情況

,你可以做到以下幾點:

formInstance.SafeInvoke(f => f.UpdateStatus(myCounterInt.toString)); 

或類似的東西。

我已經寫了有關使用該on my blog,但不給我貸款,我一直在寫關於this CodeProject article

1

我最近來到了類似的問題。

我正在寫一個網絡遊戲,我想將文本追加到文本框中,但是我會得到一個錯誤,說我試圖從不同的線程更改窗體控件,從而導致一個不安全的線程。這是因爲我在服務器端使用ASyncCallback。

我曾經這樣做過:(控制檯方法是一個簡單的方法,獲取一個字符串並將其附加到文本框中)。

console("message"); 

而要解決這個問題,我不得不改成這樣,解決問題,現在:

this.Invoke((MethodInvoker)delegate { console("message"); }); 

希望這有助於其他人遇到這個問題。這可能不是最好的方法,但它爲我做了訣竅。

問候。