2014-07-09 61 views
0

我想在Windows窗體中自動刷新標籤結果。此代碼有效,但標籤中的文本不會更改。在我看來,程序必須停止他們的操作來刷新標籤。 我也試過http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspxhttp://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(EHInvalidOperation.WinForms.IllegalCrossThreadCall);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true, ,但它也不起作用。它說線程是不同的,他們不能這樣做。此外MSNDa代碼不爲我工作:(如何在while(true)循環中在標籤中顯示結果

private void button1_Click(object sender, EventArgs e) 
    { 
     while (true) 
     { 
      CaluclateTime(); 
      Thread.Sleep(1000); 
     } 
    } 

    private void CaluclateTime() 
    { 
     DateTime zeroDateTime = new DateTime(2014, 9, 16, 15, 00, 0); 
     //zeroDateTime is a future :). 
     DateTime now = DateTime.Now; 
     TimeSpan duration = zeroDateTime - now; 
     label1.Text = String.Format("Time zero is in: {0}", duration.ToString()); 
    } 
+0

如果您使用'System.Timers.Timer'定時器,make s你可以設置'SynchronizingObject'屬性。有關示例,請參見[本答案](http://stackoverflow.com/a/24086028)。沒有它,它會拋出CrossThreadExceptions。 –

回答

1

你可以利用async/await特點:

private async void button1_Click(object sender, EventArgs e) 
{ 
    while (true) 
    { 
     CaluclateTime(); 
     await Task.Delay(1000); 
    } 
} 

,改變你的CalculateTime方法是這樣的:

if (this.InvokeRequired) 
    this.Invoke(() => label1.Text = String.Format("Time zero is in: {0}", duration.ToString())); 
else 
    label1.Text = String.Format("Time zero is in: {0}", duration.ToString()); 

也不要忘記停止你的循環。

2

你應該做的過程荷蘭國際集團在後臺線程,但如果你堅持在一個單獨的線程做,你應該讀這樣的回答:Force GUI update from UI Thread

Edit(對於相關性):調用Application.DoEvents()導致Windows窗體UI處理任何優秀的UI事件,包括Windows控件更新,如標籤文本更新。更新標籤Text屬性後立即調用此方法。

Edit(對於全面改善):有在後臺線程中運行長時間運行的進程,您可以讓用戶執行其他操作(如果你願意的話)在執行長時間運行操作的靈活性。它爲用戶提供了更好的用戶體驗,因爲用戶界面在任何時候都能夠響應用戶的需求。

在C#後臺線程技術包括:

+0

您能否將該鏈接的相關部分添加到您的答案中?只有鏈接的答案在這裏不受歡迎,因爲如果鏈接頁面被更改或刪除,它們往往變得毫無用處。 –

+0

添加了相關的代碼調用。 – toadflakz

+0

太棒了!如果您可以添加關於如何使用該方法的示例,那麼您的答案可以進一步改進,並且還提供了一些關於爲什麼您建議在後臺線程中執行處理的說明(只是說不好的東西,而不解釋爲什麼不是很好很有幫助!)。 –