如何调用task_t>通过使用Parallel

本文关键字:Parallel 何调用 调用 task | 更新日期: 2023-09-27 18:17:37

我有一个异步调用列表,按特定顺序排列,哪一个完成第一个或最后一个并不重要。所有这些async Task返回位图。所有的异步任务返回一个单一的Bitmap接受一个,它返回一个Bitmap列表。

为了测试目的,我能够更好地处理使用并行与任务的差异,我需要有人向我展示如何调用这些异步任务中的每一个,并设置一个包含所有返回的异步结果列表的局部变量。

  1. 如何并行。对于这些任务
  2. 如何检索每个已完成任务的值,并将返回的结果设置为局部变量。

——我只是一个接一个地等待每个任务的代码。

public async static Task<PdfSharp.Pdf.PdfDocument> RollUpDrawingsPDF(IElevation elevation)
{
    List<Bitmap> allSheets = new List<Bitmap>();
    var processedParts = new PartsProcessor.PartProcessor().ProcessParts(elevation);
    //elevation
    allSheets.Add(await ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone));
    //door schedules, 3 schedules per sheet
    allSheets.AddRange(await ShopDrawing.Door.GetDoorSecheduleSheets(elevation, RotateFlipType.Rotate90FlipNone, 3));
    //materials list
    allSheets.Add(await MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing());
    //optimized parts
    allSheets.Add(await Optimization.Manager.GetOptimizedParts(processedParts).GetDrawing());
    //cut sheet
    allSheets.Add(await CutSheet.Manager.GetCutSheet(processedParts).GetDrawing());
    return await PDFMaker.PDFManager.GetPDF(allSheets, true);
}

------代码我试图并行运行。然而,对于每个人来说,这不是工作,而是一个寻求帮助的起点。对于每个返回的任务结果,我需要设置并行任务结果的allSheets的局部变量。

    public async static Task<PdfSharp.Pdf.PdfDocument> RollUpDrawingsPDF(IElevation elevation)
{
    List<Bitmap> allSheets = new List<Bitmap>();
    var processedParts = new PartsProcessor.PartProcessor().ProcessParts(elevation);
    Task[] myTask = new Task[5];
    myTask[0] = ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone);
    myTask[1] = ShopDrawing.Door.GetDoorSecheduleSheets(elevation, RotateFlipType.Rotate90FlipNone, 3);
    myTask[2] = MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing();
    myTask[3] = Optimization.Manager.GetOptimizedParts(processedParts).GetDrawing();
    myTask[4] = CutSheet.Manager.GetCutSheet(processedParts).GetDrawing();

    var x = Parallel.ForEach(myTask, t => t.Wait());
    ////elevation
    //allSheets.Add(await );
    ////door schedules, 3 schedules per sheet
    //allSheets.AddRange(await);
    ////materials list
    //allSheets.Add(await );
    ////optimized parts
    //allSheets.Add(await );
    ////cut sheet
    //allSheets.Add(await );
    return await PDFMaker.PDFManager.GetPDF(allSheets, true);
}

我将如何实现并行。这段代码的ForEach ?

*讨论代码示例。如何在其他方法返回一个Bitmap*

时返回一个List
async Task<Bitmap[]> RollUpHelper(IElevation elevation, PartsProcessor.ProcessedParts       processedParts)
            {
                return await Task<Bitmap[]>.WhenAll(
 ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone),
                     //ShopDrawing.Door.GetDoorSecheduleSheets(elevation,RotateFlipType.Rotate90FlipNone, 3),
                     MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing(),
                     MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing(),
                     CutSheet.Manager.GetCutSheet(processedParts).GetDrawing()
                      );
            }

如何调用task_t>通过使用Parallel

Parallel.ForEach()用于并行运行多个同步操作。

您希望等待多个异步 Task完成:

await Task.WhenAll(tasks);

对SLaks的回答进行扩展:

Task.WhenAll()将返回由它等待的任务返回的所有结果的数组,所以你不需要自己管理。

这里有一个例子,我使用string而不是Bitmap在你的例子。请注意,其中一个工人没有返回List<string>,我将其转换为具有一个项目的List<string>,以使其与其他工人相同的类型。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    namespace Demo
    {
        class Data
        {
            public string Value;
            public Data(string value) { Value = value; }
        }
        class Program
        {
            async Task<List<string>[]>  RunAsync()
            {
                return await Task.WhenAll
                (
                    Task.Factory.StartNew(() => 
                        new List<string> {Worker1(new Data("One"))}),
                    Task.Factory.StartNew(() => 
                        Worker2(new Data("Two"))),
                    Task.Factory.StartNew(() => 
                        Worker3(new Data("Three")))
                );
            }
            void Run()
            {
                var results = RunAsync().Result;
                // Now results is an array of List<string>, so we can iterate the results.
                foreach (var result in results)
                {
                    result.Print();
                    Console.WriteLine("--------------");
                }
            }
            string Worker1(Data data)
            {
                Thread.Sleep(1000);
                return data.Value;
            }
            List<string> Worker2(Data data)
            {
                Thread.Sleep(1500);
                return Enumerable.Repeat(data.Value, 2).ToList();
            }
            List<string> Worker3(Data data)
            {
                Thread.Sleep(2000);
                return Enumerable.Repeat(data.Value, 3).ToList();
            }
            static void Main()
            {
                new Program().Run();
            }
        }
        static class DemoUtil
        {
            public static void Print(this object self)
            {
                Console.WriteLine(self);
            }
            public static void Print(this string self)
            {
                Console.WriteLine(self);
            }
            public static void Print<T>(this IEnumerable<T> self)
            {
                foreach (var item in self)
                    Console.WriteLine(item);
            }
        }
    }