c# - 为 UI 响应异步调用同步函数

标签 c# winforms async-await

我有一个同步方法 GetReports(),它的返回值将用于设置 UI 控件的数据源。运行可能需要一段时间。像下面这样异步调用它是惯用的方式吗?

var l = new List<...>();
await Task.Run(() => l = GetReports().ToList());
UIControl.DataSource = l;

最佳答案

您应该使用 Microsoft 的 Reactive Framework(又名 Rx)- NuGet System.Reactive.Windows.Forms 并添加 using System.Reactive.Linq; - 然后您可以做这个:

IDisposable subscription =
    Observable
        .Start(() => GetReports().ToList())
        .ObserveOn(UIControl)
        .Subscribe(list => UIControl.DataSource = list);

这很好地推送到一个新线程,然后在更新 DataSource 之前将其拉回。

如果您需要在完成之前取消,只需调用 subscription.Dispose();

如果您对 GetReports 的调用是可取消的,那么您可以这样做:

IDisposable subscription =
    Observable
        .FromAsync(ct => GetReports(ct))
        .Select(x => x.ToList())
        .ObserveOn(UIControl)
        .Subscribe(list => UIControl.DataSource = list);

调用 subscription.Dispose() 现在也会取消任务。

关于c# - 为 UI 响应异步调用同步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54953428/

相关文章:

c# - 泛型 List<T>.Contains() 中的值与引用相等性

c# - 反向表单点击?

c# - 单元测试和多个异步任务

c# - 在 Entity Framework 中使用存储过程,如何让实体填充其导航属性?

c# - dotnet ef 数据库更新无法加载文件或程序集“Microsoft.Extensions.FileProviders.Abstractions”

c# - 如何将屏蔽的文本框值设置为十进制数?

c# - 异步/等待和返回任务是否相同?

c# - Azure Durable Functions 如何恢复?

c# - 无法加载文件或程序集 'EntityFramework' 或其依赖项之一

c# - 如何使用计时器每 x 秒更改一次标签文本