C# 如何实现多线程并并行执行多个任务?

C# 如何实现多线程并并行执行多个任务?,c#,multithreading,parallel-processing,C#,Multithreading,Parallel Processing,我是线程编程新手。我必须在并行和后台运行几个任务(以便主UI执行线程保持对用户操作的响应),并在继续执行之前等待每个任务完成 比如: foreach(MyTask t in myTasks) { t.DoSomethinginBackground(); // There could be n number of task, to save // processing time I wish to run each of them

我是线程编程新手。我必须在并行和后台运行几个任务(以便主UI执行线程保持对用户操作的响应),并在继续执行之前等待每个任务完成

比如:

foreach(MyTask t in myTasks)
{
  t.DoSomethinginBackground(); // There could be n number of task, to save 
                               // processing time I wish to run each of them 
                               // in parallel
}

// Wait till all tasks complete doing something parallel in background


Console.Write("All tasks Completed. Now we can do further processing");
我知道有几种方法可以实现这一目标。但我正在寻找在.NET4.0(C#)中实现的最佳解决方案

您可以使用库来完成:

 string[] urls = ...;
 var tasks = urls.Select(url => Task.Factory.StartNew(() => DoSomething(url)));
要避免锁定UI线程,可以在.NET 4.0中使用:

Task.Factory.ContinueWhenAll(tasks.ToArray(), _ => 
    Console.Write("All tasks Completed. Now we can do further processing");
);

如果您使用的是.NET的最新版本,则可以使用
任务。在我看来,您可能需要使用
任务

您还可以在一个循环中执行多个任务

List<string> results = new List<string>(myTasks.Count);
Parallel.ForEach(myTasks, t =>
{
    string result = t.DoSomethingInBackground();
    lock (results)
    { // lock the list to avoid race conditions
        results.Add(result);
    }
});

如果使用NET4.0或更高版本,请参考并行类和任务类。约瑟夫·阿尔巴哈里(Joseph Albahari)对此写了一本非常清晰的书:

如何实现我的任务?好吧,我的任务可以是任何东西。这不要紧。在我的实际解决方案中,我有一个URL数组,我必须为它们中的每一个获取HTML(Web废弃)。感谢Nolonar,到目前为止似乎是一个整洁的解决方案。但是,如果每个任务返回一个值(比如字符串值),我必须在继续之前合并每个任务的返回字符串,该怎么办?换言之,当其他任务仍然繁忙时,每个任务是否能在完成时返回值?不,第二个代码块对我来说似乎是一个很好的解决方案。为了在后台运行任务,我可以将BackgroundWorker与PLINQ一起使用吗?@Aakash我不知道你说的将BackgroundWorker与PLINQ一起使用是什么意思。你可以在后台工作人员中使用PLINQ,如果这是你要问的。是的,这正是我的意思。我创建了一个BackGroundWorker实例,并在DoWork()方法中使用PLINQ并行运行每个任务。每个任务都返回一个字符串集合,我使用AddRange()方法将其存储在字符串的全局集合中。我想知道DoWork是否可以将一个值作为参数发送给RunWorkerCompleted事件。比如,如果我在DoWork中声明一个局部变量,并在RunWorkerCompleted中传递它?谢谢Huy,当然会这样做,看来是时候深入研究多线程了。迟早要做的事我仍然认为第二块代码应该在Main以外的其他线程上运行。
List<string> results = new List<string>(myTasks.Count);
Parallel.ForEach(myTasks, t =>
{
    string result = t.DoSomethingInBackground();
    lock (results)
    { // lock the list to avoid race conditions
        results.Add(result);
    }
});
worker.RunWorkerAsync();
worker.RunWorkerAsync(argument); // argument is an object