Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 代理开始一次调用更多线程_C#_Multithreading_Delegates - Fatal编程技术网

C# 代理开始一次调用更多线程

C# 代理开始一次调用更多线程,c#,multithreading,delegates,C#,Multithreading,Delegates,我正在写一个代理检查程序。我使用它来管理线程 que = new Queue<Proxy>(_settings.Proxies); while (que.Count > 0) { lock (que) { while (running >= _settings.Threads) {} Proxy cProxy = que.Dequeue(); CheckProxyAsync(cProxy);

我正在写一个代理检查程序。我使用它来管理线程

que = new Queue<Proxy>(_settings.Proxies);

while (que.Count > 0)
{
    lock (que)
    {
        while (running >= _settings.Threads) {}

        Proxy cProxy = que.Dequeue();
        CheckProxyAsync(cProxy);
        Console.WriteLine(running);
    }
}
这是我的回拨:

private void Callback(IAsyncResult ar)
{
    var returnTuple = InvokeDelegate.EndInvoke(ar);
    if (!returnTuple.Item1) //if failed
    {
        if (!_settings.Retry || returnTuple.Item2.Retries > _settings.RetryCount) //if no retry or retry count is reached
            _settings.Proxies.Remove(returnTuple.Item2); //Dead proxy :(
        else que.Enqueue(returnTuple.Item2); //try again
    }
    else //if success
    {
        Interlocked.Increment(ref filteredProxies);
        Interlocked.Decrement(ref leftProxies);

        if (returnTuple.Item2.ProxyAnonymity == Anonymity.L1)
            Interlocked.Increment(ref l1Proxies);
        else if (returnTuple.Item2.ProxyAnonymity == Anonymity.L2)
            Interlocked.Increment(ref l2Proxies);
        else if (returnTuple.Item2.ProxyAnonymity == Anonymity.L3)
            Interlocked.Increment(ref l3Proxies);

    }
    OnUpdate();

}
正如您在manager函数中看到的,我将运行线程计数打印到控制台。计数在委托“InvokeDelegate”所属的函数“CheckProxy”的开始和结束处得到更新。 但是并行运行异步方法的最大值是8,但是我想要更多!
如何增加限制?

将此问题留给线程池处理。它几乎肯定比您更了解线程的最佳数量

基本上,您的CPU一次只能执行这么多操作。创建超过一定数量的线程会增加大量开销,核心会不断交换当前应该执行的线程,而不会增加额外的吞吐量。一旦达到这一点,添加线程将提高每个操作的响应能力,并提高启动速度,但以总吞吐量为代价


如果您真的想拥有更多的线程,那么就不需要使用线程池,而是显式地创建线程。但是如果你要这样做,你应该确实知道你在做什么,并且知道为什么线程池的分配算法不适合你。

你应该知道你的延迟循环,
在(运行>=\u settings.Threads){}
时可能无法终止。编译器可以生成假定值不变的代码。另外,这是一个繁忙的等待循环,本质上是一个CPU。你可以考虑一种更便宜的延迟方法。一个
Semaphore
将是一个很好的方法。@JimMischel A
BlockingCollection
会更好,因为它将代表您管理所有的同步。@Servy:可能吧。
BlockingCollection
很难限制并发线程的数量。@JimMischel不需要这样做。您创建并填充BC,开始X个工作单位,并让每个人在完成时从BC获得下一个工作单位。这导致X消费者。BC不会创建这些使用者,您可以创建,但是可以给所有这些使用者一个BC来管理到所有这些工作者的数据管道。@Servy:我明白您的意思。重新构造程序,以便X线程根据需要从队列中提取项目,而不是由主线程进行编排。但在这种情况下,我必须等待代理响应的大部分时间!所以它根本不是CPU密集型的!那么,对于委托/托管任务,就没有办法做到这一点了?所以我必须切换到线程?@user3676570如果它不是CPU绑定的工作,那么你不需要一堆线程来管理工作。您只需要多个线程来管理CPU限制的工作。当你有IO绑定的工作时,除非你做一些愚蠢的事情,比如创建一个线程,它的唯一目的是坐在那里对该IO执行阻塞等待,否则没有线程需要做任何事情来处理异步IO。@user3676570你需要意识到这一点。你太棒了!我真的很喜欢你解释事情的方式!我希望我现在能更好地理解它!但我不知道如何在我的代理检查器中实现它!我知道我并不真的需要多线程,因为它不是cpu密集型的。你能给我介绍一个学习TPL的好资源吗?哦,如果我没弄错的话,那就是.Net 4.5附带的
async
wait
操作符?我说得对吗?
private void Callback(IAsyncResult ar)
{
    var returnTuple = InvokeDelegate.EndInvoke(ar);
    if (!returnTuple.Item1) //if failed
    {
        if (!_settings.Retry || returnTuple.Item2.Retries > _settings.RetryCount) //if no retry or retry count is reached
            _settings.Proxies.Remove(returnTuple.Item2); //Dead proxy :(
        else que.Enqueue(returnTuple.Item2); //try again
    }
    else //if success
    {
        Interlocked.Increment(ref filteredProxies);
        Interlocked.Decrement(ref leftProxies);

        if (returnTuple.Item2.ProxyAnonymity == Anonymity.L1)
            Interlocked.Increment(ref l1Proxies);
        else if (returnTuple.Item2.ProxyAnonymity == Anonymity.L2)
            Interlocked.Increment(ref l2Proxies);
        else if (returnTuple.Item2.ProxyAnonymity == Anonymity.L3)
            Interlocked.Increment(ref l3Proxies);

    }
    OnUpdate();

}