有朋有問到 按下button_click時 程式是由下一秒啟動,
所以很直覺想到跟在背景做事,執行完成後,再更新到UI的行為,
所以可以利用Task讓程式不要Block UI,再透過Task.ContinueWith將結果更新的UI
有時某些程式需要執行時(如取得WebPage的內容),不想要Block住UI,最後完成後再將資料更新到UI上。
這時可以利用Task去執行,最後要更新UI時,再透過Task.ContinueWith將結果呈現出來。
以下我們使用讀取WebPage的內容為範例,按下「取得URL內容」的Button後,會起一個Task去做事,所以UI並不會被Block住。如下,
private void btnGetURL_Click(object sender, EventArgs e)
{
btnGetURL.Enabled = false;
string url = txtURL.Text;
//讓被Call的程式從下一秒開始執行
Task<string> waitT = Task.Factory.StartNew(() =>
{
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
return client.DownloadString(url);
});
waitT.ContinueWith(antecendent =>
{
//將內容傳寫到TextBox上
txtBody.Text = antecendent.Result;
btnGetURL.Enabled = true;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
那如果還要加入取消的話,就加入CancellationTokenSource來控制取消,如下,
CancellationTokenSource tokenSource;
//取得網頁的內容
private void btnGetURL_Click(object sender, EventArgs e)
{
tokenSource = new CancellationTokenSource();
btnGetURL.Enabled = false;
btnCancel.Enabled = true;
string url = txtURL.Text;
//讓被Call的程式從下一秒開始執行
Task<string> waitT = Task.Factory.StartNew(() =>
{
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
return client.DownloadString(url);
}, tokenSource.Token);
waitT.ContinueWith(antecendent =>
{
//將內容傳寫到TextBox上
txtBody.Text = antecendent.Result;
btnGetURL.Enabled = true;
btnCancel.Enabled = false;
}, tokenSource.Token, TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}
//取消取得網頁的內容
private void btnCancel_Click(object sender, EventArgs e)
{
if (tokenSource != null)
{
tokenSource.Cancel();
btnGetURL.Enabled = true;
btnCancel.Enabled = false;
txtBody.Text = "使用者取消!";
}
}
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^