2014-01-08 39 views
0

我的情况很简单但很复杂。我正在尝试编写一个程序,它需要一次执行1100次外部进程,每次执行4次。我完全沉迷于如何去做这件事。我正在编写的应用程序是一个“Windows窗体应用程序”,我正在使用BackgroundWorker来运行异步任务。同时运行给定数量的相同进程

例子,我有1100个不同的字符串列表,我想运行每串的过程中1次,但只有4个在同一时间,然后移动到下一个4

任何帮助将不胜感激。

+0

为什么只有4?这是由于处理器核心吗? – Bas

+1

[[Parallel.ForEach]](http://msdn.microsoft.com/zh-CN/library/dd783747%28v=vs.110%29.aspx)与['ParallelOptions。 MaxDegreeOfParallelism'](http://msdn.microsoft.com/en-US/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism%28v=vs.110%29.aspx)设置为4应该让你开始。 –

+0

主要应用程序是一个WinForms,但工作进程是什么类型的应用程序?此外,您的标签'多线程'和'backgroundworker'适用于并发线程,而不适用于进程。 – nicholas

回答

6

考虑下面的代码:

private async void CodeOnUiThread() 
{ 
    //do ui stuff before starting 
    await ExecuteProcesses(); 
    //do ui stuff after completing. 
} 

private async Task ExecuteProcesses() 
{ 
    await Task.Factory.StartNew(() => 
    { 
     List<string> myStrings = GetMyStrings(); //or whatever you need 
     Parallel.ForEach(myStrings, 
      new ParallelOptions() 
      { 
       MaxDegreeOfParallelism = 4 
      }, (s) => 
      { 
       var process = new Process(); 
       process.StartInfo = new ProcessStartInfo("myProcess.exe", s); 
       process.Start(); 
       process.WaitForExit(); 

      }); 
    }); 
} 

这允许最大的4个线程,以同时放运行,因此不允许超过4个流程,以在同一时间执行。

更新:

您还可以使用Environment.ProcessorCount获得内核的数量。但是,默认情况下,Parallel.ForEach调用将正确处理此问题。

更新2

Parallel.ForEach会阻塞线程当前正在运行。我已经更新了上面的代码。

+0

巨大的感谢,我想你已经指出我在正确的方向。如果我假设在后台工作者上运行此代码以保持我的UI响应,那就没问题了。 –

+0

标记为答案,因为它肯定是我想要的,但在UI线程上运行它会锁定我的表单,直到过程完成。 –

+1

道歉@WilliamRiley,Parallel.ForEach是一个阻塞呼叫。我已经更新了答案。 – Bas

1

这个怎么样(完整的例子):一次

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<StringContainer> strContainers = new List<StringContainer>(); 
     for (int i = 0; i < 1100; i++) 
     { 
      strContainers.Add(new StringContainer() { str = "string" + i }); 
     } 

     Parallel.ForEach(
      strContainers, 
      new ParallelOptions() { MaxDegreeOfParallelism = 4 }, 
      x => ProcessString(x)); 

     foreach (var item in strContainers) 
     { 
      Console.WriteLine(item.str); 
     } 

     Console.ReadKey(); 
    } 

    private static void ProcessString(StringContainer strContainer) 
    { 
     strContainer.str += "_processed"; 
    } 
} 

public class StringContainer 
{ 
    public string str; 
} 
相关问题