c# - Gui becomes less responsive -
first of such great community. i've learned lot questions , answers here. first question on s.o., please gentle :)
ok, first things first:
-1st code version:
private async void buttonwebscrap_click(object sender, eventargs e) { clicklink("/ptk/sun/core/cookie/cookieshandler.accept"); await task.delay(750); if (_backgroundtaskrunning || !clicklink("msisdn-change")) return; _backgroundtaskrunning = true; await longtaskasync(); } private async task longtaskasync() { const string previous = "msisdn-pool-prev"; const string next = "msisdn-pool-next"; var tempnumbers = new list<object>(); while (true) { await task.delay(750); var document = webbrowser.documenttext; var htmldoc = new htmlagilitypack.htmldocument(); htmldoc.loadhtml(document); var numbers = htmldoc.documentnode.selectnodes("//a[starts-with(@id, 'msisdn')]"); tempnumbers.addrange(from number in numbers number.id != previous && number.id != next select number.innertext.removeenters().removespaces().replacespecificchars()); tempnumbers.add("-------------------------"); if (tempnumbers.count >= 24) { listboxnumbers.items.addrange(tempnumbers.toarray()); tempnumbers.clear(); } if (clicklink(next) == false) { break; } } } private bool clicklink(string linkid) { if (webbrowser.document != null) { var elementbyid = webbrowser.document.getelementbyid(linkid); if (elementbyid != null) { elementbyid.invokemember("click"); } else { return false; } if (webbrowser.document.window != null) { webbrowser.document.window.scrollto(0, 480); } } else { return false; } return true; }
-2nd code version:
private void mainform_load(object sender, eventargs e) { _webbrowserdocuments = new concurrentqueue<string>(); _uischeduler = taskscheduler.fromcurrentsynchronizationcontext(); _progress = new progress<string>(); _progress.progresschanged += (o, s) => _objects.add(s); _objects = new bindinglist<string>(); listboxnumbers.datasource = _objects; } private void mainform_formclosing(object sender, formclosingeventargs e) { webbrowseremulation.delete(); } private async void buttonwebscrap_click(object sender, eventargs e) { await webbrowserclicklinkasync("/ptk/sun/core/cookie/cookieshandler.accept"); if (_backgroundtaskrunning || !(await webbrowserclicklinkasync("msisdn-change"))) return; await task.delay(5000); var cts = new cancellationtokensource(); await webbrowserdocumentdownloadasync(cts); await documentparseasync(_progress, cts); _backgroundtaskrunning = true; } private async task documentparseasync(iprogress<string> progress, cancellationtokensource cts) { await task.factory.startnew(() => { while (true) { string tempdocument; if (_webbrowserdocuments.trydequeue(out tempdocument)) { var htmldoc = new htmlagilitypack.htmldocument(); htmldoc.loadhtml(tempdocument); var numbers = htmldoc.documentnode.selectnodes("//a[starts-with(@id, 'msisdn')]"); foreach (var number in numbers.where(number => number.id != previous && number.id != next). select(x => x.innertext.removeenters().removespaces().replacespecificchars())) { progress.report(number); } progress.report("-------------------------"); } if (cts.iscancellationrequested) { break; } } }, cts.token); } private async task webbrowserdocumentdownloadasync(cancellationtokensource cts) { await task.factory.startnew(async () => { while (true) { await task.delay(1000); _webbrowserdocuments.enqueue(webbrowser.documenttext); if (await webbrowserclicklinkasync(next)) continue; cts.cancel(); break; } }, new cancellationtoken(), taskcreationoptions.none, _uischeduler); } private async task<bool> webbrowserclicklinkasync(string linkid) { return await task.factory.startnew(() => { if (webbrowser.document != null) { var elementbyid = webbrowser.document.getelementbyid(linkid); if (elementbyid != null) { elementbyid.invokemember("click"); } else { return false; } if (webbrowser.document.window != null) { webbrowser.document.window.scrollto(0, 480); } } else { return false; } return true; }, new cancellationtoken(), taskcreationoptions.none, _uischeduler); }
on beggining working fine, after webscrapping 500 of numbers, "gui" little bit sluggish. don't know if "bad" understanding of async/await pattern, or else. thought second version better task - it's still sluggish :/. can me this?
why i'm using webbrowser control instead of webclient? know lot easier, site i'm webscrapping made (as see it) java (jsessionid) + ajax, , there aren't "proper" links.
if need more details, write ;)
thanks in advance.
edit:
second version using methods returning task (or task) simplify await current synchronizationcontext mainform (only 2 of those)
first version first approach of using await/async (as can see longtaskasync() method async await task.delay())
this finished code (without thinks getting synchronizationcontext, setting listbox.datasource bindlist, etc.) 3 controls on winform - webbrowser, listbox , button ;)
the slowdown due adding values user interface.
during looping, you're adding items list box:
if (tempnumbers.count >= 24) { listboxnumbers.items.addrange(tempnumbers.toarray()); tempnumbers.clear(); }
as more , more results, list box display become bottleneck, , cause things slow down. since list box must updated on ui thread, cause ui less responsive on time.
your second option worse, add items bindinglist<t>
1 item @ time in second option, , each addition cause refresh of ui.
this mitigated using listview virtualmode set true, prevents addition of new items forcing refresh on screen.
Comments
Post a Comment