我的问题来自 an article斯蒂芬·克利里。
基本上,有一个标签
<Label Content="{Binding UrlByteCount.Result}"/>
它由 viewmodel c.tor 设置
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
到现在为止还挺好。
现在我做一个微不足道的改变:
UrlByteCount = new NotifyTaskCompletion<int>(MyStaticService.ImmediateSet(-1));
已经定义
public static Task<int> ImmediateSet(int res)
{
var tcs = new TaskCompletionSource<int>();
tcs.SetResult(res);
return tcs.Task;
}
显然标签立即显示-1。
好的,然后我添加一个带有viewmodel命令绑定(bind)的按钮,因为我想在单击按钮时设置标签。
跳过所有礼仪部分(委托(delegate)命令等),核心功能再次是:
private void TestLogic()
{
UrlByteCount = new NotifyTaskCompletion<int>( // FIX ME
MyStaticService.CountBytesInUrlAsync("http://www.example.com")); // FIX ME
}
我完全知道它不起作用并且标签的内容将保持-1,但我想知道哪种方法是解决这个问题的最佳方法?
问题的第二部分。
假设您已经找到了第一部分的解决方案,并且点击按钮异步更改了标签的内容(保持 ui 响应性),您能否确认以下代码是否是防止“双击”(即“多次单击”)的一致方式处决”)?
private async void TestLogic()
{
canRun = false;
((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
await FoundASolution();
canRun = true;
((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
}
private async Task<int> FoundASolution()
{
await Task.Delay(TimeSpan.FromSeconds(10));
return 21;
}
最佳答案
假设您在 UrlByteCount
中引发属性更改事件,您的代码应该可以正常工作。二传手。您绑定(bind)到 UrlByteCount.Result
的事实并不意味着只更改 UrlByteCount
时绑定(bind)不会刷新- 它会。
至于你的第二部分 - 可以通过制作 Command.CanExecute
来禁用按钮错误并通过 Command.CanExecuteChanged
通知此事事件,在开始长时间运行操作之前。即使操作因异常而失败,只要确保您再次启用它(因此包装在 try-finally block 中)。您可能希望通知用户有关错误并允许他修复它(或者稍等一下,例如,如果错误是网络故障),然后重试操作,这在您的情况下是不可能的 - 按钮将保持禁用以防万一的错误。
关于c# - 异步 MVVM - 如何更改 NotifyTaskCompletion.Result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36956334/