更新應用程式
使用者介面處理的是簡單程式碼。當計時器失效時它會生效,而且程式碼會更新計時器的顯示。這一更新必須改變文字,或控制背景。如下所示:
MyTime.Background = newBrush;
MyTime.Content = label;
計時器在背景執行緒上執行,所以你需要透過使用 Dispatcher.Invoke() 邊界線執行呼叫。這兩行程式碼是你想列入 lambda 運算式的程式碼,不是證明方法定義的邏輯理由。但是我之前就講過 lambda 不會與 Dispatcher.Invoke 一起執行,除非是你使用了具體的代表定義才行。這之中的一部分已經在 .Net 框架 3.5 中定義了。我們可以使用內嵌代表定義並對它們進行分配,這些都是的該解決方案比起先前提到過的案例都要省事一些。這兩行程式碼也要求一對參數:一個用於文字的字串和用於背景顏色的顏色刷。這意味著你需要使用的代表定義要考慮到這兩個參數並返回無效值:
Action<string, Brush> 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() 方法避免了由於使用了方法參數的參數陣列而造成的若干多載問題。它使用的是一個我們想要執行的抽象代表型別。