0

非同期メソッドから 2 つの異なるタスクを実行しようとしていますが、2 番目のタスクは最初のタスクが終了した場所からのみ開始する必要があります。ContinueWith を使用しようとしましたが、成功しませんでした。これは私のサンプルコードです:

class Program
{
    static List<string> GlobalList1 = null;
    static List<string> GlobalList2 = null;

    static void Main(string[] args)
    {
        Task firstTask = new Task(DoFirstThing);
        firstTask.Start();
        firstTask.Wait();

        Task secondTask = firstTask.ContinueWith(o => DoSecondThing(), TaskContinuationOptions.ExecuteSynchronously);
        secondTask.Wait();

        Console.ReadKey();
    }

    public async static void DoFirstThing()
    {
        Console.WriteLine("Doing first...");

        Task t = new Task(FirstThing);
        t.Start();

        await t;
    }

    public async static void DoSecondThing()
    {
        Console.WriteLine("Doing second...");

        Task t = new Task(SecondThing);
        t.Start();


        await t;
    }

    private async static void FirstThing()
    {
        Console.WriteLine("In First..");

        Task t = new Task(() =>
        {
            List<string> list = new List<string>();

            for (int i = 0; i < 1000; i++)
            {
                list.Add(string.Format("Testing:{0}", i));
            }

            System.Threading.Thread.Sleep(2000);

            GlobalList1 = list;
        });

        t.Start();

        await t;
    }

    private async static void SecondThing()
    {
        Console.WriteLine("In Second...");

        Task t = new Task(() =>
        {
            GlobalList2 = new List<string>();
            for (int i = 0; i < GlobalList1.Count; i++)
            {
                GlobalList2.Add(GlobalList1[i].ToString() + " - testing");
            }
        });

        t.Start();
        await t;
    }
}

コンソール出力から、タスクが同時に実行されていることに気付くかもしれません。この動作を変更することは可能ですか?

4

1 に答える 1

5

私の2番目のタスクは、最初のタスクが終了した場所からのみ開始する必要があります

それから、それが終わるのを心から待つべきです。現在、あなたはそうしていません。DoFirstThingメソッドが戻るのを待っていますが、 awaiting が終了するtに戻ります。

新しい を構築してTaskから を呼び出す代わりにStart()、 を呼び出しTask.Runて を提供するFunc<T>場合は、プロキシ タスクが完了するのを待つことができます。

static void Main(string[] args)
{
    Task firstTask = Task.Run(DoFirstThing);
    firstTask.Wait();
    ...
}

public async static Task DoFirstThing()
{
    Console.WriteLine("Doing first...");

    Task t = Task.Run(FirstThing);

    await t;
}

private async static Task FirstThing() { ... }

これで、非同期操作がWait()完全に完了するまで、呼び出しは完了しません。FirstThing()

async void基本的に、ほとんどの場合、メソッドは避けてください。

それは言った:

  • 単に非同期メソッドを呼び出すのではなく、明示的にタスクを開始することは、通常はお勧めできません。
  • Wait()特定のタスクに同じスレッドで実行する必要がある継続がある場合、デッドロックする可能性があるため、タスクを待機するのではなく、明示的に呼び出すこともめったに良い考えではありません。
于 2016-04-19T12:00:13.860 に答える