C# 3.0 saves my life as GUI developer
事先聲明,我是”食人口水尾“的,不是原作者。
UI thread-safe update 一直是件麻煩的事,Winform 如是,Swing 亦如是。Winform 裡用 Control.InvokeRequired, Control.Invoke;Swing 則有 SwingUtilities.invokeLater。兩者都能叫 developer 快樂到死。.NET developer 比較幸運,因為 C# 的演進間接令 thread-safe UI processing 變得簡單。
C# 1.0 + .NET Framework 1.x
public delegate void UpdateStatusBarDelegate(string status);
public void UpdateStatusBar(string status)
{
if (InvokeRequired)
{
Invoke(new UpdateStatusBarDelegate(UpdateStatusBar), new object[] { status });
return;
}
statusBar.Text = status;
}
真的醜死了。一行簡單的 assignment statement 忽爾變得好擁腫。幾乎每次 update UI 都要給它一個新的 delegate,好想哭出來。
C# 2.0 + .NET Framework 2.0
public void UpdateStatusBar(string status)
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(delegate { UpdateStatusBar(status); }));
return;
}
statusBar.Text = status;
}
到 2.0 年代事情美好了,但只是這麼一點點。MethodInvoker 出現減少了無謂的 delegate,但整體感覺依然嘔心。
C# 3.0 + .NET Framework 3.5
public void UpdateStatusBar(string status)
{
this.SafeInvoke(() =>
{
statusBar.Text = status;
});
}
public static class ControlExtensions
{
public delegate void InvokeHandler();
public static void SafeInvoke(this Control control, InvokeHandler handler)
{
if (control.InvokeRequired)
{
control.Invoke(handler);
}
else
{
handler();
}
}
}
就是應該這樣嘛!簡潔多了。多虧 Extension Method 和 Lambda Expression ,生命從未試過如此美好。那個 ControlExtensions class 只要寫一次,以後便無痛無癢。帥吧。C# 3.0 真是好東西,會令人寫上癮的。