c# - 如何使用 .NET 4.5 或更高版本以异步方式获取驱动器、文件夹或文件?
问题描述
已编辑
我设计了一个 WPF UserControl,用于列出驱动器。但是,某些驱动器是网络存储(例如 NAS),可能处于睡眠模式。然后访问那些驱动器非常慢(第一次响应时间超过10秒)。因此,我希望我的 UserControl 显示进度条或其他内容以通知用户“我没有崩溃”,而不是让他们等待 GUI 响应 10 秒。
根据@TheGeneral 的建议,我使用 async/await 作为我的解决方案,代码如下所示:
private async Task refreshDriveAsync()
{
DriveInfo[] drives = await Task.Run(() => DriveInfo.GetDrives());
//do my stuff here
}
调用者看起来像:
//void is not good, but there's no error handling, so it's might ok here
public async void Refresh()
{
//some stuff
await refreshDriveAsync();
//some more stuff
}
在显示 UserControl 之后,它应该调用Refresh()
一次。所以我写了一段这样的代码:
public MyUserControl()
{
Window w = this.GetParentWindow(); //my own extension method
if (window != null)
window.Loaded += ((t, e) => Refresh());
}
我的预期结果是: 1. 显示窗口。2. 我的用户控件还没有准备好,但是我可以显示一个通知。3. 10 秒后,用户控件获取驱动器,并刷新其内容。
然而,真实世界是: 1. 显示窗口,但没有任何 UI 元素。2. 10 秒后,显示所有 UI 元素,包括我的用户控件。
请对这种情况有什么建议吗?
解决方案
只需将其卸载到一个Task.Run
和await
那个。
var drives = await Task.Run(() => DriveInfo.GetDrives());
基本上,这会将工作负载卸载到线程池线程并在 UI 上下文上创建延续。还有其他方法可以做到这一点,但是这将释放 UI(以线程池线程为代价)
推荐阅读
- excel - Excel 公式查找
- javascript - 在材料 ui Avatar 组件上悬停时显示用户的名称
- html - 嵌套 HTML 结构中的 CSS 属性继承和覆盖
- java - 如何使二叉搜索树的遍历方法返回 Java 中的字符串?
- cmake - 我可以让 CMake 的 Make 生成器为“开销”命令添加 silencing-@ 吗?
- java - BigQuery 流插入错误 - 在数组之外添加重复记录
- java - 带抽屉布局的底部导航 | onBackPressed 在片段中
- excel - 将列表中的多个图像合并为 PDF
- python - 如何在 python 中以特定采样率输出 1 位音频?
- wordpress - add_rewrite_rule 在父主题中工作但不在子主题中