带插槽的C#多线程

Mar*_*o M 7 .net c# multithreading

我有此功能,用于检查代理服务器,当前仅检查多个线程,并等待所有线程完成,直到下一个线程开始。从允许的最大线程数完成后,是否可以立即启动一个新线程?

for (int i = 0; i < listProxies.Count(); i+=nThreadsNum)
{                              
    for (nCurrentThread = 0; nCurrentThread < nThreadsNum; nCurrentThread++)
    {
        if (nCurrentThread < nThreadsNum)
        {
           string strProxyIP = listProxies[i + nCurrentThread].sIPAddress;
           int nPort = listProxies[i + nCurrentThread].nPort;
                    tasks.Add(Task.Factory.StartNew<ProxyAddress>(() => CheckProxyServer(strProxyIP, nPort, nCurrentThread)));
        }
     }                

     Task.WaitAll(tasks.ToArray());

     foreach (var tsk in tasks)
     {
        ProxyAddress result = tsk.Result;
        UpdateProxyDBRecord(result.sIPAddress, result.bOnlineStatus);
     }

     tasks.Clear();                
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*Kee 5

这似乎更简单:

int numberProcessed = 0;
Parallel.ForEach(listProxies,
  new ParallelOptions { MaxDegreeOfParallelism = nThreadsNum },
  (p)=> {
    var result = CheckProxyServer(p.sIPAddress, s.nPort, Thread.CurrentThread.ManagedThreadId);
    UpdateProxyDBRecord(result.sIPAddress, result.bOnlineStatus);
    Interlocked.Increment(numberProcessed);
});
Run Code Online (Sandbox Code Playgroud)

带插槽:

var obj = new Object();
var slots = new List<int>();
Parallel.ForEach(listProxies,
  new ParallelOptions { MaxDegreeOfParallelism = nThreadsNum },
  (p)=> {
    int threadId = Thread.CurrentThread.ManagedThreadId;
    int slot = slots.IndexOf(threadId);
    if (slot == -1)
    {
      lock(obj)
      {
        slots.Add(threadId);
      }
      slot = slots.IndexOf(threadId);
    }
    var result = CheckProxyServer(p.sIPAddress, s.nPort, slot);
    UpdateProxyDBRecord(result.sIPAddress, result.bOnlineStatus);
});
Run Code Online (Sandbox Code Playgroud)

我在那里采取了一些捷径来保证线程安全。您不必进行常规的check-lock-check舞动,因为永远不会有两个线程尝试将相同的threadid添加到列表中,因此第二次检查将始终失败并且不需要。其次,出于相同的原因,我认为您也不需要锁定外部IndexOf。这使得它成为一个非常高效的并发例程,无论可枚举中有多少项,它很少会锁定(它应该仅锁定nThreadsNum次)。