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 回答