gpt4 book ai didi

带槽的 C# 多线程

转载 作者:太空狗 更新时间:2023-10-29 20:09:17 26 4
gpt4 key购买 nike

我有这个检查代理服务器的功能,目前它只检查一些线程并等待所有线程完成,直到下一组开始。是否有可能在一个线程从允许的最大值完成后立即启动一个新线程?

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();
}

最佳答案

这看起来简单多了:

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);
});

有插槽:

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);
});

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

关于带槽的 C# 多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57681149/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com