1

特定の順序で並べられた非同期呼び出しのリストがあり、どちらが最初に終了するか最後に終了するかは問題ではありません。これらの非同期タスクはすべてビットマップを返します。すべての非同期タスクは、1 つの Bitmap Accept を返し、Bitmaps List のリストを返します。

テスト目的で、Parallel を使用する場合と単に Task を使用する場合の違いをより適切に処理できるようにするために、これらの非同期タスクのそれぞれを呼び出す方法と、返されたすべての非同期のリストを含むローカル変数を設定する方法を誰かに教えてもらう必要があります。結果。

  1. これらのタスクの Parallel.ForEach の方法
  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);
}

------コード Parallel.ForEach で実行しようとしていますが、これは機能していませんが、ヘルプの出発点です。返されたタスク結果ごとに、その Parallel Task Result の 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);
}

このコード本体に Parallel.ForEach を実装するにはどうすればよいですか?

*ディスカッション コードの例。他のメソッドが 1 つのビットマップを返すときにリストを返す方法*

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

            }
4

2 に答える 2

0

SLaks の回答を拡張するには:

Task.WhenAll()待機したタスクによって返されたすべての結果の配列が返されるため、自分で管理する必要はありません。

stringこれは、あなたの例の代わりに使用Bitmapする例です。ワーカーの 1 つが a を返さないことに注意してください。他のアイテムと同じ型にするために、それを 1 つのアイテムで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);
            }
        }
    }
于 2013-06-07T18:21:07.040 に答える