热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

这些1k线程来自哪里-Wheredothese1kthreadscomefrom

Iamtryingtocreateaapplicationthatmultithreadeddownloadsimagesfromawebsite,asaintrod

I am trying to create a application that multi threaded downloads images from a website, as a introduction into threading. (never used threading properly before)

我正在尝试创建一个多线程从网站下载图像的应用程序,作为线程的介绍。 (之前从未正确使用过线程)

But currently it seems to create 1000+ threads and I am not sure where they are coming from.

但目前它似乎创造了1000多个线程,我不确定它们来自哪里。

I first queue a thread into a thread pool, for starters i only have 1 job in the jobs array

我首先将一个线程排入一个线程池,对于初学者我在jobs数组中只有一个作业

foreach (Job j in Jobs)
{
    ThreadPool.QueueUserWorkItem(Download, j);
}

Which starts the void Download(object obj) on a new thread where it loops through a certain amount of pages (images needed / 42 images per page)

在一个新线程上启动void Download(object obj),它在一个新的线程中循环一定数量的页面(需要的图像/每​​页42个图像)

for (var i = 0; i 如果我错了,请纠正我,在同一个线程上调用下一个void

void ProcessPage(string response, bool secondPass, Job j)
{
    var wc = new WebClient();
    LinkItem[] linkRespOnse= LinkFinder.Find(response).ToArray();

    foreach (LinkItem i in linkResponse)
    {
        if (secondPass)
        {
            if (string.IsNullOrEmpty(i.Href))
                continue;
            else if (i.Href.Contains("http://loreipsum."))
            {
                if (DownloadImage(i.Href, ID(i.Href)))
                    j.Downloaded++;
            }
        }
        else
        {
            if (i.Href.Contains(";id="))
            {
                var alterRespOnse= wc.DownloadString("http://www." + j.Provider.ToString() + "/index.php?page=post&s=view&id=" + ID(i.Href));
                ProcessPage(alterResponse, true, j);
            }
        }
    }
}

And finally passes on to the last function and downloads the actual image

最后传递给最后一个函数并下载实际图像

bool DownloadImage(string target, int id)
{
    var url = new System.Uri(target);
    var fi = new System.IO.FileInfo(url.AbsolutePath);
    var ext = fi.Extension;

    if (!string.IsNullOrEmpty(ext))
    {
        using (var wc = new WebClient())
        {
            try
            {
                wc.DownloadFileAsync(url, id + ext);
                return true;
            }
            catch(System.Exception e)
            {
                if (DEBUG) Debug.Log(e);
            }
        }
    }
    else
    {
        Debug.Log("Returned Without a extension: " + url + " || " + fi.FullName);
        return false;
    }
    return true;
}

I am not sure how I am starting this many threads, but would love to know.

我不知道我是如何开始这么多线程的,但我很想知道。

Edit

The goal of this program is to download the different job in jobs at the same time (max of 5) each downloading a maximum of 42 images at the time.

该程序的目标是同时下载作业中的不同作业(最多5个),每个下载最多42个图像。

so a maximum of 210 images can/should be downloaded maximum at all times.

所以最多可以/应该最多下载210张图像。

2 个解决方案

#1


First of all, how did you measure the thread count? Why do you think that you have thousand of them in your application? You are using the ThreadPool, so you don't create them by yourself, and the ThreadPool wouldn't create such great amount of them for it's needs.

首先,你是如何衡量线程数的?为什么你认为你的应用程序中有数千个?您正在使用ThreadPool,因此您不需要自己创建它们,并且ThreadPool不会为它的需要创建如此大量的它们。

Second, you are mixing synchronious and asynchronious operations in your code. As you can't use TPL and async/await, let's go through you code and count the unit-of-works you are creating, so you can minimize them. After you do this, the number of queued items in ThreadPool will decrease and your application will gain performance you need.

其次,您在代码中混合了同步和异步操作。由于您无法使用TPL和async / await,让我们通过您的代码并计算您正在创建的工作单元,以便最小化它们。执行此操作后,ThreadPool中的排队项目数将减少,您的应用程序将获得所需的性能。

  1. You don't set the SetMaxThreads method in your application, so, according the MSDN:

    您没有在应用程序中设置SetMaxThreads方法,因此,根据MSDN:

    Maximum Number of Thread Pool Threads
    The number of operations that can be queued to the thread pool is limited only by available memory; however, the thread pool limits the number of threads that can be active in the process simultaneously. By default, the limit is 25 worker threads per CPU and 1,000 I/O completion threads.

    最大线程池线程数可以排队到线程池的操作数仅受可用内存的限制;但是,线程池会限制同时在进程中处于活动状态的线程数。默认情况下,限制为每个CPU 25个工作线程和1,000个I / O完成线程。

    So you must set the maximum to the 5.

    所以你必须将最大值设置为5。

  2. I can't find a place in your code where you check the 42 images per Job, you are only incrementing the value in ProcessPage method.

    我在代码中找不到每个Job检查42个图像的位置,只是在ProcessPage方法中增加值。

  3. Check the ManagedThreadId for the handle of WebClient.DownloadStringCompleted - does it execute in different thread or not.
  4. 检查ManagedThreadId以获取WebClient.DownloadStringCompleted的句柄 - 它是否在不同的线程中执行。

  5. You are adding the new item in ThreadPool queue, why are you using the asynchronious operation for Downloading? Use a synchronious overload, like this:

    您是在ThreadPool队列中添加新项目,为什么使用异步操作进行下载?使用同步重载,如下所示:

    ProcessPage(wc.DownloadString(downloadLink), false, j);
    

    This will not create another one item in ThreadPool queue, and you wouldn't have a sinchronisation context switch here.

    这不会在ThreadPool队列中创建另一个项目,并且您不会在此处进行同步上下文切换。

  6. In ProcessPage your wc variable doesn't being garbage collected, so you aren't freeing all your resourses here. Add using statement here:

    在ProcessPage中,您的wc变量不会被垃圾收集,因此您不会在此处释放所有资源。在此处添加using语句:

    void ProcessPage(string response, bool secondPass, Job j)
    {
        using (var wc = new WebClient())
        {
            LinkItem[] linkRespOnse= LinkFinder.Find(response).ToArray();
    
            foreach (LinkItem i in linkResponse)
            {
                if (secondPass)
                {
                    if (string.IsNullOrEmpty(i.Href))
                        continue;
                    else if (i.Href.Contains("http://loreipsum."))
                    {
                        if (DownloadImage(i.Href, ID(i.Href)))
                            j.Downloaded++;
                    }
                }
                else
                {
                    if (i.Href.Contains(";id="))
                    {
                        var alterRespOnse= wc.DownloadString("http://www." + j.Provider.ToString() + "/index.php?page=post&s=view&id=" + ID(i.Href));
                        ProcessPage(alterResponse, true, j);
                    }
                }
            }
        }
    }
    
  7. In DownloadImage method you also use the asynchronious load. This also adds item in ThreadPoll queue, and I think that you can avoid this, and use synchronious overload too:

    在DownloadImage方法中,您还使用异步加载。这也添加了ThreadPoll队列中的项目,我认为你可以避免这种情况,并使用同步重载:

    wc.DownloadFile(url, id + ext);
    return true; 
    

So, in general, avoid the context-switching operations and dispose your resources properly.

因此,通常,避免上下文切换操作并正确处理您的资源。

#2


Your wc WebClinet will go out of scope and be randomly garbage collected before the async callback. Also on all async calls you have to allow for immediate return and the actual delegated function return. So processPage will have to be in two places. Also the j in the original loop may be going out of scope depending on where Download in the original loop is declared.

您的wc WebClinet将超出范围并在异步回调之前随机进行垃圾回收。此外,对于所有异步调用,您必须允许立即返回并返回实际的委托函数。所以processPage必须在两个地方。此外,原始循环中的j可能超出范围,具体取决于声明原始循环中的下载位置。


推荐阅读
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 腾讯安全平台部招聘安全工程师和数据分析工程师
    腾讯安全平台部正在招聘安全工程师和数据分析工程师。安全工程师负责安全问题和安全事件的跟踪和分析,提供安全测试技术支持;数据分析工程师负责安全产品相关系统数据统计和分析挖掘,通过用户行为数据建模为业务决策提供参考。招聘要求包括熟悉渗透测试和常见安全工具原理,精通Web漏洞,熟练使用多门编程语言等。有相关工作经验和在安全站点发表作品的候选人优先考虑。 ... [详细]
author-avatar
明依丞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有