我已经与Task
类型。一切都很好Task
什么也不返回。例如:
XAML:
<Button Name="_button"
Click="ButtonBase_OnClick">
Click
</Button>
隐藏代码:
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<Boolean>.Factory.StartNew(() =>
{
Thread.Sleep(5*1000);
return true;
});
if (task.Result)
_button.IsEnabled = true;
}
这里我们遇到了 UI 阻塞的问题。 UI 线程被锁定,直到任务返回结果。
_button.IsEnabled = false;
因此,上面的字符串被完全忽略。
我在.Net 4.0
,所以我不能使用async/await
方法。
这个问题真让我恶心……有解决了吗?
您的主线程正在阻塞,因为调用Task.Result
等到Task
已完成。相反,你可以使用Task.ContinueWith()
访问Task.Result
after the Task
已完成。致电给TaskScheduler.FromCurrentSynchronizationContext()
导致继续在主 UI 线程上运行(因此您可以访问_button
安全)。
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_button.IsEnabled = false;
Task<Boolean>.Factory.StartNew(() =>
{
Thread.Sleep(5*1000);
return true;
}).ContinueWith(t=>
{
if (t.Result)
_button.IsEnabled = true;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Update
如果您使用 C# 5,则可以使用 async/await 代替。
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
_button.IsEnabled = false;
var result = await Task.Run(() =>
{
Thread.Sleep(5*1000);
return true;
});
_button.IsEnabled = result;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)