C# 异步MVVM-如何更改NotifyTaskCompletion.Result

C# 异步MVVM-如何更改NotifyTaskCompletion.Result,c#,wpf,mvvm,async-await,C#,Wpf,Mvvm,Async Await,我的问题源于斯蒂芬·克利里 基本上,有一个标签 <Label Content="{Binding UrlByteCount.Result}"/> 它是由viewmodel c.tor设置的 UrlByteCount = new NotifyTaskCompletion<int>( MyStaticService.CountBytesInUrlAsync("http://www.example.com")); UrlByteCount

我的问题源于斯蒂芬·克利里

基本上,有一个标签

<Label Content="{Binding UrlByteCount.Result}"/>

它是由viewmodel c.tor设置的

UrlByteCount = new NotifyTaskCompletion<int>(
                MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
UrlByteCount=new NotifyTaskCompletion(
MyStaticService.CountBytesInUrlAsync(“http://www.example.com"));
到目前为止还不错。 现在我做一个小的改变:

 UrlByteCount = new NotifyTaskCompletion<int>(MyStaticService.ImmediateSet(-1));
UrlByteCount=newnotifytaskcompletion(MyStaticService.ImmediateSet(-1));
定义

public static Task<int> ImmediateSet(int res)
{
    var tcs = new TaskCompletionSource<int>();
    tcs.SetResult(res);
    return tcs.Task;
}
公共静态任务立即集(int-res)
{
var tcs=new TaskCompletionSource();
设置结果(res);
返回tcs.Task;
}
显然,标签立即显示-1。 好的,然后我添加了一个带有viewmodel命令绑定的按钮,因为我想在单击按钮时设置标签

跳过所有仪式部分(代表命令等),核心功能再次是:

private void TestLogic()
{
    UrlByteCount = new NotifyTaskCompletion<int>( // FIX ME
        MyStaticService.CountBytesInUrlAsync("http://www.example.com")); // FIX ME
}
private void TestLogic()
{
UrlByteCount=new NotifyTaskCompletion(//修复我
MyStaticService.CountBytesInUrlAsync(“http://www.example.com);//治好我
}
我非常清楚它不起作用,标签的内容将保持-1,但我想知道哪种方法是解决这个问题的最佳方法

问题的第二部分。 假设您已经找到了第一部分的解决方案,并且单击按钮会异步更改标签的内容(保持ui响应),您能否确认以下代码是否是防止“双击”(即“多次执行”)的一致方法

private async void TestLogic()
{
canRun=false;
((DelegateCommand)TestCommand.RaiseCancecutechanged();
等待找到解决方案();
canRun=true;
((DelegateCommand)TestCommand.RaiseCancecutechanged();
}
专用异步任务FoundASolution()
{
等待任务延迟(时间跨度从秒(10));
返回21;
}

假设在
UrlByteCount
setter中引发属性更改事件,则代码应该可以正常工作。绑定到
UrlByteCount.Result
并不意味着当您只更改
UrlByteCount
时绑定将不会刷新-它会刷新


至于您的第二部分-在开始长时间运行操作之前,可以通过使
命令.CanExecute
为false并通过
命令.CanExecuteChanged
事件通知禁用按钮。只要确保再次启用它,即使操作因异常而失败(所以在try finally块中进行包装)。您可能希望将错误通知用户,并允许他修复错误(或者,如果错误是网络故障,请稍等片刻),然后重试操作,这在您的情况下是不可能的-在出现错误时,按钮将保持禁用状态。

假设您在
UrlByteCount
设置程序中引发属性更改事件,则代码应该可以正常工作。绑定到
UrlByteCount.Result
并不意味着当您只更改
UrlByteCount
时绑定将不会刷新-它会刷新


至于您的第二部分-在开始长时间运行操作之前,可以通过使
命令.CanExecute
为false并通过
命令.CanExecuteChanged
事件通知禁用按钮。只要确保再次启用它,即使操作因异常而失败(所以在try finally块中进行包装)。您可能希望将错误通知用户,并允许他修复错误(或者,如果错误是网络故障,请稍等片刻),然后重试操作,这在您的情况下是不可能的-按钮将在出现错误时保持禁用状态。

为什么它不起作用?如果在UrlByteCount的setter中引发属性更改事件,它应该可以正常工作。@Evk我假设它,因为绑定到“UrlByteCount.Result”而不是“UrlByteCount”,所以我认为执行UrlByteCount=new是不干净的。。。它不会破坏指向结果的指针吗?顺便说一句,是的,我看到它起作用了。否,当您为UrlByteCount分配新值时,绑定知道它已更改(当然假设您引发属性更改事件),即使绑定路径是UrlByteCount。Whatever1.Whatever2…@Evk OK,请回答问题。非常感谢。为什么现在要投否决票?如果您对我的问题投了反对票,因为您认为在UrlByteCount上增加更改的属性很重要,那么没有必要这样做。绑定到常规字符串属性要标准得多,而且确实有效。=>看看我的(还有我的问题,如果没有被删除的话)为什么它不起作用?如果在UrlByteCount的setter中引发属性更改事件,它应该可以正常工作。@Evk我假设它,因为绑定到“UrlByteCount.Result”而不是“UrlByteCount”,所以我认为执行UrlByteCount=new是不干净的。。。它不会破坏指向结果的指针吗?顺便说一句,是的,我看到它起作用了。否,当您为UrlByteCount分配新值时,绑定知道它已更改(当然假设您引发属性更改事件),即使绑定路径是UrlByteCount。Whatever1.Whatever2…@Evk OK,请回答问题。非常感谢。为什么现在要投否决票?如果您对我的问题投了反对票,因为您认为在UrlByteCount上增加更改的属性很重要,那么没有必要这样做。绑定到常规字符串属性要标准得多,而且确实有效。=>查看我的(以及我的问题,如果尚未删除)
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;
}