我有一个同步方法 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/