更新應用程序
用戶界面處理的是簡單代碼。當計時器失效時它會生效,而且代碼會更新計時器的顯示。這一更新必須改變文本,或控制背景。如下所示:
MyTime.Background = newBrush;
MyTime.Content = label
計時器在背景線程上運行,所以你需要通過使用Dispatcher.Invoke()邊界線執行調用。這兩行代碼是你想列入lambda表達式的代碼,不是證明方法定義的邏輯理由。但是我之前就講過lambda不會與Didpatcher.Invoke一起運行,除非是你使用了具體的代表定義才行。這之中的一部分已經在.Net框架3.5中定義了。我們可以使用嵌入式代表定義並對它們進行分配,這些都是的該解決方案比起先前提到過的案例都要省事一些。這兩行代碼也要求一對參數:一個用於文本的字符串和用於背景顏色的顏色刷。這意味著你需要使用的代表定義要考慮到這兩個參數並返回無效值:
Action updateTimer;
在聲明變量後,你可以為代碼指定需要執行的代表變量。這裡你可以使用lambda表達式,因為Action是一個具體的代表定義:
updateTimer = (label, newBrush) =>
{
MyTime.Background = newBrush;
MyTime.Content = label;
};
現在,當計時器提出事件時,你已經擁有了一些需要執行的指向該代碼的變量。接下來要做的就只是通過Dispatcher.Invoke()使用代表定義:
if (!MyTime.Dispatcher.CheckAccess())
{
MyTime.Dispatcher.Invoke(updateTimer,
newLabel, next);
}
else
updateTimer(newLabel, next);
這一過程十分簡單,但是卻要求你反復進行,因此,我們可以讓步驟變得容易一點。
這裡其實由一個簡單的模式。事件處理器可以從背景線程中調用出來。當我們使用計時器,或者異步調用Web服務以及其他類似任務的時候,你就會看到這一行為。無論是在什麼時候,我們都不清楚自己位於哪個線程之上,我們可以調用Dispatcher.CheckAccess()來決定是否可以訪問任意用戶界面控件。如果需要從線程邊界執行調用,就必須使用Dispatcher.Invoke()。Dispatcher.Invoke()方法避免了由於使用了方法參數的參數數組而造成的若干超載問題。它使用的是一個我們想要執行的抽象代表類型。