private void btnBlockTest_Click(object sender, EventArgs e)
{
//1.block UI Thread.Sleep(2000);
lblResult.Text = "Hello World";
}
這樣會Block UI..private void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
return "Hello World!";
}
);
//這裡等待Task執行結束 lblResult.Text = task.Result;
}
但還是會 Block UI..private void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
return "Hello World!";
}
);
task.ContinueWith(
(completedTask) =>
{
lblResult.Text = completedTask.Result;
}
);
}
雖然不會Block UI了,但 lblResult.Text 卻不會接收到 Task 的回傳值,因為它不在 UI Thread 中執行。private void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
throw new Exception("Task Error");
return "Hello World!";
}
);
task.ContinueWith(
(completedTask) =>
{
lblResult.Text = completedTask.Result;
}
);
}
Exception 會被吃掉,因為不在 UI Thread 中執行 ...private void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
throw new Exception("Task Error");
return "Hello World!";
}
);
task.ContinueWith(
(completedTask) =>
{
if (completedTask.IsFaulted)
{
Console.WriteLine(completedTask.Exception.ToString());
}else {
lblResult.Text = completedTask.Result;
}
}
);
}
private void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
return "Hello World!";
}
);
//way1:if the current execution context is on the UI thread. //task.ContinueWith( // (completedTask) => // { // lblResult.Text = completedTask.Result; // } // , TaskScheduler.FromCurrentSynchronizationContext());
//way2 task.ContinueWith(
(completedTask) =>
{
this.Invoke((MethodInvoker)delegate {
lblResult.Text = completedTask.Result;
});
}
);
}
嗯...這樣 lblResult.Text 值就有改變了....private async void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
return "Hello World!";
}
);
lblResult.Text = await task;
}
功能一樣,但程式碼簡潔了許多呢 ...private async void btnBlockTest_Click(object sender, EventArgs e)
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
throw new Exception("Task Error");
return "Hello World!";
}
);
lblResult.Text = await task;
}
爆了....private async void btnBlockTest_Click(object sender, EventArgs e)
{
try {
RunAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private async void RunAsync()
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
throw new Exception("Task Error");
return "Hello World!";
}
);
lblResult.Text = await task;
}
還是會發生錯誤 .... 因為 RunAsync 回傳值是 void 而不是 Task。private async Task RunAsync()
{
var task = Task.Run(
() =>
{
Thread.Sleep(2000);
throw new Exception("Task Error");
return "Hello World!";
}
);
lblResult.Text = await task;
}
雖然不會整個 Ap 都掛掉,但也沒有被 catch 攔到... 因為呼叫時,沒有加上 await ...private async void btnBlockTest_Click(object sender, EventArgs e)
{
try {
await RunAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Task.Delay(1).ContinueWith((t) => {
}, TaskScheduler.FromCurrentSynchronizationContext()
).Wait();
本文也發表於亂馬客Blog