我試圖做這樣的事情:如何在C#中的循環過程中更改控件的屬性幾次
int i;
while(true)
{
label1.Text = i.ToString();
i++;
Thread.Sleep(500);
}
(在現實中我試圖做一些更復雜,更有意義,但這是我的問題的一個簡單的例子) 我期待標籤的文本每隔1/2秒更改..但它會卡住。
感謝您
我試圖做這樣的事情:如何在C#中的循環過程中更改控件的屬性幾次
int i;
while(true)
{
label1.Text = i.ToString();
i++;
Thread.Sleep(500);
}
(在現實中我試圖做一些更復雜,更有意義,但這是我的問題的一個簡單的例子) 我期待標籤的文本每隔1/2秒更改..但它會卡住。
感謝您
你不能讓GUI線程睡眠(因爲不是GUI不會迴應)(我是說,即使我喜歡睡覺* 很多 *)。
考慮以下備選方案之一:
是的,這是真的,非常在GUI線程上睡不好的想法,它會一直卡住 – kobe
您將在運行該代碼永遠不要離開while循環,因此卡住的部分。此外,如果這是一個WinForm,您需要重新繪製/無效/刷新您的UI以查看任何更新。在這裏更多信息:C#: How do I repaint my form when it's not focused?
睡在UI線程使事情更糟,因爲直到它完成你的方法不能應對「漆」事件。
這裏最合適的選擇是一個計時器,在每個計時器上做一些工作。
一個懶惰和深刻的瑕疵的方法是添加Application.DoEvents() - 我只提到這個讓我說不要做這個!
使用後臺線程或定時器,否則會阻止用戶界面:
Thread t = new Thread(() =>
{
int i = 0;
while (true)
{
label1.Invoke(new Action(() => { label1.Text = i.ToString();}));
i++;
Thread.Sleep(500);
};
});
t.IsBackground = true;
t.Start();
你現在,你的代碼是同一個線程在GUI上運行的方式。設置新的標籤文本後,您立即進入睡眠狀態,從而防止負責實際更新屏幕的任何代碼運行。您可以在睡前呼叫Application.DoEvents()
強制它處理任何消息,但這不是一個真正的解決方案。
你需要做的是把你的耗時代碼放在不同的線程上。 .NET Timer類是爲了這樣簡單的事情而創建的。你也可以讓你自己的線程包含你的循環代碼。只要確保你只能從它創建的同一個線程訪問標籤。您可以通過將代理人傳遞給label1.Invoke
來完成實際文本更新。
最好甚至不要提及'Application.DoEvents()'作爲一個可能的解決方案。 –
它是winforms嗎? – VMAtm
你能提供更多的信息;至於它在哪裏被卡住或代碼段? – Rahul
使用斷點,看看它卡在哪裏... f10和f11應該修復你的問題 – kobe