multithreading - Updating GUI from thread C#, without binding to UI controls -
it know invoke method used when u need update gui other thread. how can implement without binding control code?
here's test class:
class test { public list<thread> threads = new list<thread>(); public int nthreads = 0; public int maxthreads = 5; public void dowork(object data) { string message = (string)data; //messagebox.show(message); } public void createthread(object data) { if (nthreads >= maxthreads) return; thread newthread = new thread(dowork); threads.add(newthread); newthread.isbackground = true; newthread.start(data); nthreads++; } public void windupthreads() { //messagebox.show("count: " + nthreads.tostring()); for(int = 0; < threads.count; i++) { if (threads[i].isalive == false) { threads[i].abort(); threads.removeat(i); //messagebox.show("removing @ " + i.tostring()); } } nthreads = threads.count; } }
the question = tecnique must use in order update gui not hardcode control class? i've tried pass delegate dowork method, doesn't work (http://pastebin.com/vasyfxpw). thanks!
i'm using winforms, .net 3.5
here's button_click handler:
private void button1_click(object sender, eventargs e) { button1.enabled = false; test thtest = new test(); string[] strings; try { strings = file.readalllines("c:\\users\\alex\\desktop\\test.txt"); } catch (exception ex) { messagebox.show(ex.message); return; } bool flag = true; int counter = 0; int datacount = strings.length; while (flag == true) { if (counter >= datacount) { flag = false; } while (thtest.nthreads < thtest.maxthreads) { if (flag == false) break; thtest.createthread(strings[counter]); //data d = new data(); //d.deleg = additem; //d.mess = strings[counter]; //thtest.createthread((object)d); //messagebox.show(counter.tostring()); counter++; } thtest.windupthreads(); if (flag == false) { { thtest.windupthreads(); } while (thtest.nthreads != 0); } } listbox1.items.add("done"); }
the idea i'am launching threads each task want process. after while i'am checking there completed tasks, being shutdowned , new ones launched until there no more tasks left.
rather making dowork
responsible updating ui results of operation performs, have return value:
//todo change type of result appropriate public string dowork(string message) { string output = "output"; //todo work come result; return output; }
then use task.run
create task
represents work being done in thread pool thread. can await task button click handler.
private async void button1_click(object sender, eventargs e) { button1.enabled = false; test thtest = new test(); //i'd note should pull out reading in file ui code; //it should in separate method, , should reading //the file asynchronously. string[] strings; try { strings = system.io.file.readalllines("c:\\users\\alex\\desktop\\test.txt"); } catch (exception ex) { messagebox.show(ex.message); return; } foreach (var line in strings) { var result = await thtest.dowork(line); listbox1.items.add(result); } listbox1.items.add("done"); }
if want old school it, can use backgroundworker
instead. work in dowork
handler, setting result (through argument) when you've computed it, , update ui result in runworkercompleted
event handler. lets keep ui , non-ui work separate, although it's far less powerful, general purpose, , extensible, newer features.
Comments
Post a Comment