首页 > 解决方案 > 如何使用 .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 元素,包括我的用户控件。

请对这种情况有什么建议吗?

标签: c#.netasync-awaituser-controls

解决方案


只需将其卸载到一个Task.Runawait那个。

var drives = await Task.Run(() => DriveInfo.GetDrives());

基本上,这会将工作负载卸载到线程池线程并在 UI 上下文上创建延续。还有其他方法可以做到这一点,但是这将释放 UI(以线程池线程为代价)


推荐阅读