14

以下に示すように、複数のタスクを作成するループがあります。各タスクの完了時に画面を更新(データを含むテキストボックスに新しい行を追加)するにはどうすればよいですか?

すべてのタスクが完了したことを検出するにはどうすればよいですか?

C#コード

 for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++)
 {
      int x = i;
      // Create a task and supply a user delegate by using a lambda expression. 
      var taskA = new Task(() => TaskRequest(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxFloodDelay.Text), x));
      // Start the task.
      taskA.Start();
 }


 private void TaskRequest(int number1, int number2, int delay, int count)
 {
      // Some long running method
 }
4

4 に答える 4

18

あなたが使用することができますContinueWith()

「ターゲットタスクが完了したときに非同期で実行される継続を作成します。」-MSDN

Task t = new Task(() => Console.WriteLine("")).ContinueWith(task => Console.Writeline("Continue With"), 
                                                            TaskScheduler.FromCurrentSynchronizationContext());
于 2013-02-10T18:54:22.307 に答える
1

お探しParallel.ForEach()ですか?

    [Test]
    public void ParallelTasks()
    {
        var strings = new List<string> {"task1", "task2", "task3"};

        Parallel.ForEach(strings, str => Console.WriteLine(str + "is done"));

        // All your parallel tasks are executed now
    }
于 2013-02-10T19:05:20.977 に答える
1

3つの単純な構成を組み合わせて使用​​することをお勧めします。

  • 単純なint numActiveTasks、タスクの作成時にインクリメントされます。つまり、タスクのInterlockedIncrement(ref numActiveTasks)直前、つまりタスクの終了時に、つまり関数の終了時にtaskA.Start()デクリメントされます。InterlockedDecrement(ref numActiveTasks)TaskRequest(...)
  • a 、タスク開始前にリセットされ、カウンターデクリメントManualResetEventにタスク終了時に通知されます
  • にあるスレッドWaitOne()は、次のManualResetEventように読み取りますnumActiveTasks

これはあなたに

  • 完了した単一タスクの通知
  • 実行されたすべてのタスクの通知(numActiveTasks <= 0)

これの主な利点は、通知が発生するスレッドについての主権を持っていることです。

于 2013-02-10T18:58:12.247 に答える
1

ユーザー12345678の回答を拡張すると、次のようなことができます。

    private void RunTasks()
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();

        List<Task> tasks = new List<Task>();
        foreach (KeyValuePair<string,string> kvp in dict)
        {
            Console.WriteLine("Executing task " + kvp.Key + " ...");
            Task t = new Task(() => MyMethod(kvp.Key, kvp.Value));
            tasks.Add(t);
            t.Start();
            t.ContinueWith(task => Console.WriteLine(kvp.Key + " completed"));

        }

        Console.WriteLine("Waiting tasks to complete...");
        Task.WaitAll(tasks.ToArray());
        Console.WriteLine("All tasks completed...");
    }

    private void MyMethod(string arg1, string arg2)
    {

    }
于 2016-07-20T22:53:05.160 に答える