简体   繁体   中英

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. 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). 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. 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:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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