简体   繁体   English

在 for 循环中使用 await 作为异步函数

[英]Using await for a async function inside a for loop

I am running a bunch of convert-to-pdf api calls through MS Graph and then returning the base64 encoded strings to the frontend for processing in pdf.js.我正在通过 MS Graph 运行一堆转换为 pdf 的 api 调用,然后将 base64 编码的字符串返回到前端以在 pdf.js 中进行处理。 However, I wanted to speed this up by adding async and await to do as many api calls as I can in the shortest time (not using batch in MS Graph).但是,我想通过添加 async 和 await 来加快速度,以便在最短的时间内执行尽可能多的 api 调用(不在 MS Graph 中使用批处理)。 However, it is unclear if this code is looping through the for loop to the next call or waiting for each await result individually which I do not want.但是,尚不清楚此代码是通过 for 循环循环到下一个调用还是单独等待我不想要的每个 await 结果。 I want to keep looping through for each request and then return the final result once all the calls have finished.我想为每个请求继续循环,然后在所有调用完成后返回最终结果。

        public async Task<ActionResult> PDFVersionsToBase64([FromForm] string ID)
    {
        //Using FormData on frontend
        //checking ID exists on searching in dashboard
        if (String.IsNullOrEmpty(ID))
        {
            return Ok(new { Result = "Failed" });
        }
        else
        {

            String query = "select * from dbo.function(@ID)";
            using (var connection = new SqlConnection(connectionString))
            {
                var documents = connection.Query<QuestionDocuments>(query, new { ID = ID});

                foreach (var file in documents)
                {
                    var fullPath = Path.Combine(fileDirectory, file.path);
                    using (var memoryStream = await oneDrive.DriveItemConvertToPdfAsync(SharedDriveID, fullPath, "path"))
                    {
                        byte[] buffer = new byte[memoryStream.Length];
                        memoryStream.Read(buffer, 0, (int)memoryStream.Length);
                         file.Base64 = Convert.ToBase64String(buffer);
                    }
                }

                return Ok(documents);

            }
        }
    }

        public async Task<Stream> DriveItemConvertToPdfAsync(string DriveID, string PathOrDriveItemID, string SearchType)
    {
        Stream response = null;
        try
        {
            var queryOptions = new List<QueryOption>()
            {
                new QueryOption("format", "pdf")
            };

            if (SearchType == "path")
            {
                response= await _graphServiceClient.Me.Drives[DriveID].Root
                .ItemWithPath(PathOrDriveItemID)
                .Content
                .Request(queryOptions)
                .GetAsync();
            }
            else if (SearchType == "id")
            {
                response = await _graphServiceClient.Me.Drives[DriveID].Items[PathOrDriveItemID]
                .Content
                .Request(queryOptions)
                .GetAsync();
            }
        }
        catch (ServiceException ex)
        {
            Console.WriteLine($"Error deleting file: {ex.ToString()}");
        }
        return response;
    }

You need to start all tasks and then wait for them all at once.您需要启动所有任务,然后同时等待它们。

var files = documents.ToArray();

var tasks = files.Select(file =>
    oneDrive.DriveItemConvertToPdfAsync(
        SharedDriveID, 
        Path.Combine(fileDirectory, file.Path), 
        "path"));

var streams = await Task.WhenAll(tasks);

for(var i = 0; i < files.Length; i++)
{
    var file = files[i];
    var stream = streams[i];
    using (var memoryStream = stream)
    {
        byte[] buffer = new byte[memoryStream.Length];
        memoryStream.Read(buffer, 0, (int)memoryStream.Length);
         file.Base64 = Convert.ToBase64String(buffer);
    }
}

Or if you want to use the ReadAsync method of the stream instead:或者,如果您想改用流的ReadAsync方法:

var tasks = documents.Select(async file => {
    var stream = await oneDrive.DriveItemConvertToPdfAsync(
        SharedDriveID, 
        Path.Combine(fileDirectory, file.Path), 
        "path");
        
    using (var memoryStream = stream)
    {
        byte[] buffer = new byte[memoryStream.Length];
        await memoryStream.ReadAsync(buffer, 0, (int)memoryStream.Length);
        file.Base64 = Convert.ToBase64String(buffer);
    }
});

await Task.WhenAll(tasks);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM