我一直在閱讀很多關於C#,WPF和Silverlight線程化的知識,但無法讓它工作。WPF中的易線程問題
我的主要問題是我有_load(_Initialized)操作,它有很多的對象創建,並且我有定時器在做不同的事情,這會導致程序的啓動時間非常緩慢,很明顯導致用戶界面掛起,這對於部署到很多用戶來說不是一件好事。
我的計時器更改標籤和文本框的值,但讓他們在另一個線程上這樣做顯然是不行的。
那麼有人可以給我一些關於如何實現我需要做的事情的例子嗎?
感謝
我一直在閱讀很多關於C#,WPF和Silverlight線程化的知識,但無法讓它工作。WPF中的易線程問題
我的主要問題是我有_load(_Initialized)操作,它有很多的對象創建,並且我有定時器在做不同的事情,這會導致程序的啓動時間非常緩慢,很明顯導致用戶界面掛起,這對於部署到很多用戶來說不是一件好事。
我的計時器更改標籤和文本框的值,但讓他們在另一個線程上這樣做顯然是不行的。
那麼有人可以給我一些關於如何實現我需要做的事情的例子嗎?
感謝
訣竅是你的UI邏輯必須在UI線程上執行。有提供的方法使其比其他方法更容易,但使用它們可能會非常棘手。下面是我如何在過去所做的那樣:
首先,你必須要聲明一個代理,你可以喂到Dispatcher.Invoke方法:
private delegate void UIDelegate();
然後你就可以得到你的後臺工作的設置和調用它的方法的RunWorkerAsync:
BackgroundWorker loadWorker = new BackgroundWorker();
loadWorker.DoWork += new DoWorkEventHandler(loadWorker_DoWork);
loadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(loadWorker_RunWorkerCompleted);
loadWorker.RunWorkerAsync();
然後,更新UI元素,你必須調用調度員:
private void changeStatusLabel(string status)
{
progressLabel.Dispatcher.Invoke(new UIDelegate(delegate
{
progressLabel.Content = status;
}));
}
這些都是從較大的方法中分離出來的,它們可能會進行一些優化。不過,這會給你一個從一開始的地方。
把你的工作到其他線程,並使用Dispatcher.Invoke元帥標籤和文本字段的設置返回到您的UI線程。
這就是說,如果可以的話,你也可以重構你的工作使用BackgroundWorker class。進度和完成事件已經封送回UI線程,因此在許多情況下更容易更新UI。
Ahem。我確實認爲你的意思是Dispatcher.Invoke。如果您不同意,請回滾。 –
@亨克:任何一個都可以使用。如果我只是設置標籤或其他類似的東西,我經常使用BeginInvoke而不是Invoke,因爲沒有理由等待操作完成。 - http://msdn.microsoft.com/en-us/library/ms591206.aspx –
是的,我的錯誤。最近我看到幾個Delegate.BeginInvokes類似的答案。 –
感謝所有的信息,我試了一下,但loadWorker_DoWork()會怎麼樣呢?如果我有這樣的標籤:this.label.Content = getCurrentUsage()。ToString();我怎樣才能把它放在計時器中呢? –
loadWorker_DoWork與您的計時器事件完全相同,並且是您需要使用Dispatcher.Invoke更新UI的位置。 –
或者您可以使用BackgroundWorker的進度報告委託,該委派在UI線程上運行,用於此目的。 –