【问题标题】:Run long operation when Property Changed属性更改时运行长时间操作
【发布时间】:2017-10-30 00:08:03
【问题描述】:

当我的属性引发 PropertyChanged 事件时,如何运行一些长时间的操作? 示例:

class SomeClass : INotifyPropertyChanged
{
    public ObservableConllection<Item> Items { get; set; }
    public string Path
    {
         get => _path;
         if (_path != value) {
             _path = value;
             OnPropertyChanged(nameof(Path));
             // await Task.Run(()=> long operation, for example load some Items use "_path");
    }
}

属性不能是异步的,我认为这是“正常的”。但是我该怎么办? 我认为这种情况经常发生。

【问题讨论】:

  • 您可以插入属性更改事件并在那里执行您的异步任务
  • 恕我直言,如果设置属性需要在后台启动长时间运行的方法,您应该考虑将其转换为方法并正确命名。我不希望有这样的副作用。无论如何,如果值快速变化会发生什么。您是否必须中止正在运行的任务?您也必须考虑这一点。
  • 尝试将其移动到事件中。例如。加载,用户事件或其他东西并使该事件异步

标签: c# .net wpf async-await task-parallel-library


【解决方案1】:

您可以在不使用await 的情况下使用Task.Run。视情况而定,它可能会也可能不会奏效,对此没有普遍的答案。

您可以创建这样的方法来设置值,这是一种更可靠的方法。但是,如果您需要数据绑定,这是行不通的:

public async Task SetPath(string value)
{
     if (_path != value) {
         _path = value;
         OnPropertyChanged(nameof(Path));
         await Task.Run(()=> ...);
}

如果您需要数据绑定并想使用await,那么最好的做法是使用 Timer 去抖动 - 您不希望在不限制用户的情况下使用一些昂贵的操作,以便他可以冻结或使应用崩溃。

【讨论】:

  • 是的,我需要绑定的问题。
  • 如前所述,Task.Run in get 本身不会造成任何问题。我将再添加一个使用 Timer 的选项。
【解决方案2】:

您应该阅读 Stephen Cleary 关于异步数据绑定属性的 MSDN 文章,其中他定义了一个名为 NotifyTaskCompletion&lt;T&gt; 的“任务观察器”类,该类实现了 INotifyPropertyChanged 接口并具有一个可以绑定到的 Result 属性:

异步编程:异步 MVVM 应用程序的模式:数据绑定: https://msdn.microsoft.com/en-us/magazine/dn605875.aspx

public class MainViewModel : INotifyPropertyChanged
{
    public string Path
    {
        get { return _path; }
        set
        {
            if (_path != value)
            {
                _path = value;
                OnPropertyChanged(nameof(Path));
                AsyncProperty = new NotifyTaskCompletion<int>(YourAsyncMethod());
            }
        }
    }

    public NotifyTaskCompletion<string> AsyncProperty { get; private set; }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 2019-08-03
    • 2011-11-30
    • 2018-04-28
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2022-06-17
    相关资源
    最近更新 更多