c# - Where do these 1k threads come from -
i trying create application multi threaded downloads images website, introduction threading. (never used threading before)
but seems create 1000+ threads , not sure coming from.
i first queue thread thread pool, starters have 1 job in jobs array
foreach (job j in jobs) { threadpool.queueuserworkitem(download, j); } which starts void download(object obj) on new thread loops through amount of pages (images needed / 42 images per page)
for (var = 0; < pages; i++) { var downloadlink = new system.uri("http://www." + j.provider.tostring() + "/index.php?page=post&s=list&tags=" + j.tags + "&pid=" + * 42); using (var wc = new webclient()) { try { wc.downloadstringasync(downloadlink); wc.downloadstringcompleted += (sender, e) => { response = e.result; processpage(response, false, j); }; } catch (system.exception e) { // unity editor equivalent of console.writeline debug.log(e); } } } correct me if wrong, next void gets called on same thread
void processpage(string response, bool secondpass, job j) { var wc = new webclient(); linkitem[] linkresponse = linkfinder.find(response).toarray(); foreach (linkitem 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 passes on last function , downloads 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 extension: " + url + " || " + fi.fullname); return false; } return true; } i not sure how starting many threads, love know.
edit
the goal of program download different job in jobs @ same time (max of 5) each downloading maximum of 42 images @ time.
so maximum of 210 images can/should downloaded maximum @ times.
first of all, how did measure thread count? why think have thousand of them in application? using threadpool, don't create them yourself, , threadpool wouldn't create such great amount of them it's needs.
second, mixing synchronious , asynchronious operations in code. can't use tpl , async/await, let's go through code , count unit-of-works creating, can minimize them. after this, number of queued items in threadpool decrease , application gain performance need.
you don't set
setmaxthreadsmethod in application, so, according msdn:maximum number of thread pool threads
number of operations can queued thread pool limited available memory; however, thread pool limits number of threads can active in process simultaneously. by default, limit 25 worker threads per cpu , 1,000 i/o completion threads.so must set maximum
5.i can't find place in code check
42images per job, incrementing value inprocesspagemethod.- check
managedthreadidhandle ofwebclient.downloadstringcompleted- execute in different thread or not. you adding new item in
threadpoolqueue, why using asynchronious operation downloading? use synchronious overload, this:processpage(wc.downloadstring(downloadlink), false, j);this not create 1 item in
threadpoolqueue, , wouldn't have sinchronisation context switch here.in
processpagewcvariable doesn't being garbage collected, aren't freeing resourses here. addusingstatement here:void processpage(string response, bool secondpass, job j) { using (var wc = new webclient()) { linkitem[] linkresponse = linkfinder.find(response).toarray(); foreach (linkitem 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); } } } } }in
downloadimagemethod use asynchronious load. adds item inthreadpollqueue, , think can avoid this, , use synchronious overload too:wc.downloadfile(url, id + ext); return true;
so, in general, avoid context-switching operations , dispose resources properly.
Comments
Post a Comment