【问题标题】:How to process only last Task and discard previous in c#如何只处理最后一个任务并在c#中丢弃上一个任务
【发布时间】:2019-09-03 06:49:46
【问题描述】:

我有一个 WPF 应用程序。窗口包括用于显示数据的数据网格和用于搜索数据的按钮。在 viewmodel 中有一种将数据加载到数据网格的方法。

    public List<MyObject> DataGridData { get; set; }

    public void LoadDataToDatagrid(object obj)
    {
        Task.Run(() =>
        {
            DataGridData = new List<MyObject>(repository.GetData());
        });
    }

每次单击按钮加载数据时,数据都会加载到数据网格中,但需要很长时间。因此,当我多次单击该按钮时,将加载第一个数据。我将开始使用它们,然后再次加载新数据。

如何停止以前的任务并仅为最后一次点击按钮加载数据?

感谢您的回答

【问题讨论】:

标签: c# asynchronous


【解决方案1】:

您可以在内容加载之前禁用该按钮?

您必须将按钮禁用属性设置为依赖于 ViewModel 中的布尔值,然后在添加到数据网格时将其设置为 true,然后在完成后将其设置为 false。 为此,我假设您可以引发以下事件:

NotifyPropertyChanged();

在 XAML 中你会做这样的事情:

<Button IsEnabled="{Binding CanClose}"/>

CanClose 是 ViewModel 中的布尔值。当你改变布尔的状态时,你必须引发某种事件。您也可以先禁用按钮,然后开始填充数据网格,完成后再次启用它?

【讨论】:

  • 这是答案,因此您不需要最后的评论。不过你可以给出一些示例代码
  • 但是当我禁用按钮时,会冻结我的应用程序。我还有一些过滤器设置,为了简单起见,我没有在这里提及。
  • 它不应该冻结你的应用程序。如果您使用的是 fx 之类的框架。 Caliburn Micro 或 Prism,然后所有这些东西使它更平滑。
【解决方案2】:

已解决:

List<CancellationTokenSource> tokens = new List<CancellationTokenSource>();

public List<MyObject> DataGridData { get; set; }

public void LoadDataToDatagrid(object obj)
{
        foreach (var token in tokens)
            token.Cancel();

        CancellationTokenSource tokenSource = new CancellationTokenSource();
        tokens.Add(tokenSource);

        var task = Task.Run(() =>
        {
            return repository.GetData();
        }, tokenSource.Token);

        try
        {
            DataGridData = await task;
        }
        finally
        {
            tokenSource.Dispose();
            tokens.Remove(tokenSource);
        }
}

该代码仅显示上次方法调用的数据,而无需冻结应用程序。 感谢 Dmitry Bychenko 的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多