[.NET]利用Task讓程式不要Block UI,再透過Task.ContinueWith將結果更新的UI

有朋有問到 按下button_click時 程式是由下一秒啟動,
所以很直覺想到跟在背景做事,執行完成後,再更新到UI的行為,
所以可以利用Task讓程式不要Block UI,再透過Task.ContinueWith將結果更新的UI

有時某些程式需要執行時(如取得WebPage的內容),不想要Block住UI,最後完成後再將資料更新到UI上。

這時可以利用Task去執行,最後要更新UI時,再透過Task.ContinueWith將結果呈現出來。

以下我們使用讀取WebPage的內容為範例,按下「取得URL內容」的Button後,會起一個Task去做事,所以UI並不會被Block住。如下,

image


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來控制取消,如下,

image

image


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:從零開始的軟體開發生活

請大家繼續支持 ^_^