400 個のバッチ ファイルがあり、10 個のバッチ ファイルを同期的に実行し、最初の 10 個のファイルがすべて終了したら、次の 10 個のファイルを実行したいと考えています。
私は c# を使用しており、以前は process.start() を使用していました。
助言がありますか?
400 個のバッチ ファイルがあり、10 個のバッチ ファイルを同期的に実行し、最初の 10 個のファイルがすべて終了したら、次の 10 個のファイルを実行したいと考えています。
私は c# を使用しており、以前は process.start() を使用していました。
助言がありますか?
.NET 4.0 以降で利用可能な Task Parallel Library (TPL) (タスク オブジェクト) を使用します。
やりたいこととは異なりますが、MSDN から取得したサンプルを次に示します: http://msdn.microsoft.com/en-us/library/dd537609.aspx
public class Example
{
public static void Main()
{
// Create the task object by using an Action(Of Object) to pass in the loop
// counter. This produces an unexpected result.
Task[] taskArray = new Task[10];
for (int i = 0; i < taskArray.Length; i++) {
taskArray[i] = Task.Factory.StartNew( (Object obj) => {
var data = new CustomData() {Name = i, CreationTime = DateTime.Now.Ticks};
data.ThreadNum = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("Task #{0} created at {1} on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum);
},
i );
}
Task.WaitAll(taskArray);
}
}
セマフォクラスを使用する必要があるようです。Semaphore を使用して、ファイルにアクセスできるスレッドの数を制限できます。
例えば:
private static int _fileProcessed;
private static Semaphore _pool;
static void Main(string[] args)
{
// let say I have a list of file names in an array
string[] files = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "z" };
// we only want 10 threads working at one time
_fileProcessed = 0;
_pool = new Semaphore(10, 10);
foreach (string file in files)
{
_pool.WaitOne(); // wait until I have a free resource
Thread t = new Thread(() => ProcessFile(file));
t.Start();
}
// you can either wait here until are theads are done
// or exit
// In the example I want to wait
while (_fileProcessed < files.Length)
{
Thread.Sleep(500);
}
Console.WriteLine("We are done!");
//Console.ReadLine();
}
private static void ProcessFile(string fileName)
{
int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("{0} - {1:HH:mm:ss.fff} - Working on File: {2}", id, DateTime.Now, fileName);
// Do Work ....
// to simulate work getting done - get a number of seconds
// between 10 & 30 seconds
Thread.Sleep(GetWorkLength());
Console.WriteLine("{0} - {1:HH:mm:ss.fff} - Worked Completed on file: {2}", id, DateTime.Now, fileName);
Interlocked.Add(ref _fileProcessed, 1);
_pool.Release();
}
// Random work length
private static Random _workLength = new Random();
private static object _lock = new object();
private static int GetWorkLength()
{
lock (_lock)
{
return _workLength.Next(10, 30) * 1000;
}
}
出力は次のとおりです。