C# - backgroundworker getting data continuously from Arduino via serial -
so have c# application getting values (6 variables) arduino. used timer calls read functionts every 100ms hangs ui , responds little heavy. want use backgroundworker continuously reads variables. put read calls in dowork method , put values in variables c# , assign them in label or something. doesn't work. (sorry english)
namespace testtemp { public partial class tempreaderform : form { public tempreaderform() { initializecomponent(); } communicator comport = new communicator(); boolean portconnection = false; string red_light1; private void button1_click(object sender, eventargs e) { if (comport.connect(57600, "i'm arduino", 4, 8, 16)) { label1.text = "connection successful - connected "+comport.port; portconnection = true; backgroundworker1.runworkerasync(); // not sure if here should start backgroundworker. } else { label1.text = "not connected . . . "; portconnection = false; } } private void groupbox1_paint(object sender, painteventargs e) { graphics ellipse1 = groupbox1.creategraphics(); brush red_on = new solidbrush(color.red); brush red_off = new solidbrush(color.darkred); label2.text = "red : " + red_light1; //here label want show "1" if "red_light1" "1" , "0" if "red_light1" "0" if (red_light1 == "1") ellipse1.fillellipse(red_on, 250, 133, 24, 24); else ellipse1.fillellipse(red_off, 250, 133, 24, 24); // here want (the label.text part see value) want color ellipse depending on "red_light1" value. } private void backgroundworker1_dowork(object sender, doworkeventargs e) { while (true) { red_light1 = comport.message(4, 8, 32); } } } } }
note: tryied "label1.text = red_light1" in dowork method says can't give values variables created in thread, this.
the "problem" backgroundworker lives thread , you're trying use in in ui thread. , message doesn't communicated there.
there 3 options:
to use
runworkercompleted
event: have use timer run backgroundworker every x ms.private void timer1_tick(object sender, eventargs e) { this.backgroundworker.runworkerasync(); } private void backgroundworker1_dowork(object sender, doworkeventargs e) e.result = comport.message(4, 8, 32); } private void backgroundworker1_runworkercompleted(object sender, runworkercompletedeventargs e) { label2.text = e.result.tostring(); }
use
begininvoke
set textprivate void backgroundworker1_dowork(object sender, doworkeventargs e) { while (true) { this.begininvoke((action)(() => { label2.text = comport.message(4, 8, 32); }); // add delay here well... } }
use
task
instead of backgroundworker , call in timer.private void timer1_tick(object sender, eventargs e) { task.run(() => { this.begininvoke((action)(() => { label2.text = comport.message(4, 8, 32); }); }); }