2014-01-08 82 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; 
} 
相關問題