Управляйте потоками с помощью Задачи - PullRequest
0 голосов
/ 25 мая 2011

В некотором коде, подобном этому

for (int i = 0; i < length; i++) //each iteration in another task
{
     Method2();

}
//Task.WaitAll()

public void Method2()
{
    Method3();
}

public void Method3()
{
    Method4();
}

public void Method4()
{
    process1.Start(); //this process take a lot of time so next iteration/next task should start in this place
}

Я бы хотел запустить каждую итерацию в другом потоке, но не все в одном.Один поток должен перейти к Method4 (), запустить его и дождаться окончания этого процесса.Позже другой поток с тем же поведением и т. Д. И в Task.WaitAll () программа должна ждать всех потоков.

Как это сделать?2 задачи за одну итерацию, ContinueWith или sth?

Ответы [ 2 ]

1 голос
/ 25 мая 2011

Не беспокойся.

Все итерации быстро заканчиваются выполнением Method4 (), и вам нужен этот однопоточный.

При таком ограничении это вообще не сценарий для задач или потоков.


Но если предположить, что в Method2 () и / или Method3 () происходит нечто существенное, вы можете заменить цикл for() на Parallel.For() и использовать простой lock вокруг кода процесса:

private static object processLock = new object();  // probably static

public void Method4()
{
   lock(processLock)
   {
       process1.Start(); 
   }
}

Но теперь вы должны остерегаться того, чтобы TPL создавал слишком много потоков. (используйте DegreeOfParallelism в Parallel.For).

0 голосов
/ 25 мая 2011

Если я правильно понимаю, вы хотите запускать все эти процессы в Paraller, но вы хотите ограничить количество одновременно запускаемых процессов, верно?Для этого вы можете использовать семафоры, которые ограничивают параллелизм (но имейте в виду, что все потоки будут все ожидающие все время - поэтому пометьте их как LongRunning).

Другое дело, что вы должны ждать в Method4 для завершения процесса.

static SemaphoreSlim semaphore = new SemaphoreSlim (3); // Capacity of 3

List<Task> tasks = new List<Task>();
for (int i = 0; i < length; i++) //each iteration in another task
{
     tasks.Add(Task.Factory.StartNew(() =>
     {
         Method2();
     }, 
     TaskCreationOptions.LongRunning);
}
Task.WaitAll(tasks)

public void Method2()
{
    Method3();
}

public void Method3()
{
    Method4();
}

public void Method4()
{
    semaphore.Wait();
    process1.Start(); 
    process1.WaitForExit();
    semaphore.Release();
}
...