XAML:
Click
CS
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_button.IsEnabled = false;
Task.Factory.StartNew(() =>
{
Thread.Sleep(5*1000);
Dispatcher.Invoke(new Action(() => _button.IsEnabled = true));
});
}
这很好用.但我希望Task返回一些值,例如Boolean.所以我需要使用Task< Boolean>:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_button.IsEnabled = false;
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(5*1000);
return true;
});
if (task.Result)
_button.IsEnabled = true;
}
这里我们遇到了UI阻塞问题. UI线程被锁定,直到任务将返回结果.
_button.IsEnabled = false;
最佳答案
您的主线程正在阻塞,因为对Task.Result的调用将等待,直到Task完成.相反,您可以在Task完成后使用Task.ContinueWith()访问Task.Result.对TaskScheduler.FromCurrentSynchronizationContext()的调用导致继续在主UI线程上运行(因此您可以安全地访问_button).
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_button.IsEnabled = false;
Task.Factory.StartNew(() =>
{
Thread.Sleep(5*1000);
return true;
}).ContinueWith(t=>
{
if (t.Result)
_button.IsEnabled = true;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
更新
如果您使用的是C#5,则可以使用async / await.
async/await 的解决方案刚好解决了当前我遇到的问题,因为异步使用了等待结果返回,所以导致UI卡死状态,
原文地址:https://codeday.me/bug/20190528/1173806.html