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
setmaxthreads
method 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
42
images per job, incrementing value inprocesspage
method.- check
managedthreadid
handle ofwebclient.downloadstringcompleted
- execute in different thread or not. you adding new item in
threadpool
queue, why using asynchronious operation downloading? use synchronious overload, this:processpage(wc.downloadstring(downloadlink), false, j);
this not create 1 item in
threadpool
queue, , wouldn't have sinchronisation context switch here.in
processpage
wc
variable doesn't being garbage collected, aren't freeing resourses here. addusing
statement 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
downloadimage
method use asynchronious load. adds item inthreadpoll
queue, , 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