使用Task控制线程

本文关键字:线程 控制线 控制 Task 使用 | 更新日期: 2023-09-27 17:57:33

在一些类似的代码中

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项任务,继续还是什么?

使用Task控制线程

不用麻烦。

所有迭代都会很快执行Method4(),并且您希望使用单线程。

在这种限制下,这根本不是任务或线程的场景。


但是,假设Method2()和/或Method3()中发生了实质性的事情,您可以将for()循环替换为Parallel.For(),并在Process代码周围使用一个简单的lock

private static object processLock = new object();  // probably static
public void Method4()
{
   lock(processLock)
   {
       process1.Start(); 
   }
}

但现在你必须防止TPL创建太多线程。(在Parallel.For中使用DegreOfParallelism).

如果我理解正确,你想在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();
}