I'm working on a Blazor project.
I try to make a asynchronous function to get ".avi" and ".mkv" files from directory. But When I try to access the page instead of having my "Loading..." message, it takes times until I got all the result in one time.

以下是我的服务代码:

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>
}

我是不是误解了异步函数的某些方面?

推荐答案

GetFilesAsync返回的是Task<IEnumerable<FileInfo>>.假设你的意图是不同步地完成所有的工作,那就是一个问题.这项工作不是作为完成Task<T>名的一部分完成的,而是作为列举IEnumerable<T>名的一部分.如果希望将所有工作卸载到ThreadPool,请确保将该方法的返回类型更改为Task<FileInfo[]>(返回FileInfo数组的Task).数组(和列表)被materialized .可枚举序列通常不是,因为它们可以用deferred execution实现.

Csharp相关问答推荐

使用WinSCP和C#将文件从STP服务器上的一个目录复制到另一个目录

如何使用PDFSharp将文本添加到现有PDF

FileStream. FlushAsync()是否确保文件被写入磁盘?

安装附加的. exe与Visual Studio

try 在Blazor项目中生成html

可为空的泛型属性

限制特定REST API不被访问,但部署代码

如何在C#中从正则表达式中匹配一些数字但排除一些常量(也是数字)

附加标题不起作用,而添加则起作用

在C#中,将两个哈希集连接在一起的时间复杂度是多少?

NET8 Maui&;iOS:AppCenter崩溃错误

我的MRG32k3a算法实现返回的数字超出了预期的[0,1]范围

如何在C#中转换泛型包装类内部的派生类

如何在用户在线时限制令牌生成?

如何使用.NET Aspire从Blazor应用程序与GRPC API通信?

序列化过程中的死循环

如何在C# WinForm控件中使用Windows 10/11的黑暗主题?

将两个for循环更改为一条LINQ语句

项目参考和方法签名问题

实体框架允许您具有筛选的属性吗?