从目录获取文件的异步函数未按预期工作

问题描述 投票:0回答:1

我正在开发 Blazor 项目。
我尝试创建一个异步函数来从目录中获取“.avi”和“.mkv”文件。但是,当我尝试访问该页面而不是看到“正在加载...”消息时,需要花费一些时间才能一次性获得所有结果。

这是我的服务代码:

namespace FilesScanner
{
    public class FilesScannerService
    {
        public async Task<IEnumerable<FileInfo>> GetFilesAsync(string path,
            EnumerationOptions options, string[] extensions)
        {
            DirectoryInfo dir = new(path);

            return await Task.Run(() => extensions.SelectMany(x => dir.EnumerateFiles(x, options)
                .Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden))));
        }
    }
}

有 Blazor 页面的代码,我在其中调用上述函数:

using FilesScanner;
using Microsoft.AspNetCore.Components;

namespace MovieLibrary.Pages
{
    public partial class Files
    {
        [Inject] private FilesScannerService _scannerService { get; set; }

        public IEnumerable<FileInfo> FilesInfos { get; set; }

        protected override async Task OnInitializedAsync()
        {
            string path = @"C:\Users\username\Videos";

            string[] extensions =
            {
                "*.avi",
                "*.mkv"
            };

            EnumerationOptions opts = new()
            {
                IgnoreInaccessible = true,
                RecurseSubdirectories = true
            };

            FilesInfos = await _scannerService.GetFilesAsync(path, opts ,extensions);
        }
    }
}

最后是我显示结果的代码:

@page "/files"
@using System.IO;
<h3>Movies</h3>

@if (FilesInfos is not null)
{
    try
    {
        int i = 1;
        foreach (FileInfo file in FilesInfos)
        {
            <p><span style="font-weight:700">@i :</span> @Path.GetFileNameWithoutExtension(@file.Name)</p>
            i++;
        }
    }
    catch (UnauthorizedAccessException ex)
    {
        <p>@ex.Message</p>
    }
}
else
{
    <h2>LOADING...</h2>
}

我是否误解了异步函数?

c# file asynchronous
1个回答
0
投票

GetFilesAsync
返回
Task<IEnumerable<FileInfo>>
。假设您的意图是异步完成所有工作,那就是一个问题。这项工作不是作为完成
Task<T>
的一部分完成的,而是作为枚举
IEnumerable<T>
的一部分完成的。如果您想将所有工作卸载到
ThreadPool
,请确保将该方法的返回类型更改为
Task<FileInfo[]>
(返回
Task
数组的
FileInfo
)。数组(和列表)被具体化。可枚举序列通常不是,因为它们可以通过延迟执行来实现。

© www.soinside.com 2019 - 2024. All rights reserved.