26. marts 2007 - 11:57Der er
7 kommentarer og 1 løsning
BackgroundWorker kan man sætte værdi i anden tråd i dowork event?
Som overskriften siger.
Kan det på nogen måde lade sig gøre at sætte værdier for UI controls som f.eks. textboxes, fra en anden tråd end hvor den er oprettet i?
Eller er det bare mig der misforstår noget? Jeg kan nemlig sagtens sætte værdierne via RunWorkerCompleted eventet, men det køres jo også på samme tråd og ikke en seperat en ligesom DoWork event gør!
Og hvis man kun kan opdatere sit UI fra samme tråd alligevel, hvad er så meningen med at bruge 2 tråde?
Er det mig der bare ikke fatter det?? Har nu læst nogle artikler om tråde, men mangler vist en brik for at få puslespillet til at gå op!
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Det er jo kun UI controls som er mit "problem". Jeg kan sagtens få en backgroundworker til at virke...
Pt. gør jeg bare det at jeg laver en række private stings, int osv i min kode. Dem kan jeg sagtens sætte værdier til gennem mit "dowork" event på min background worker.
Men så skal jeg efterfølgende når "RunWorkerCompleted" evented fyres af, overføre værdierne til mine controls på min form.
Og det synes jeg bare er sådan lidt dobbeltarbejde.
Lille eksempel som virker for mig :
public partial class frm_main : Form {
private string1; private string2;
public frm_main() { InitializeComponent(); backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
Forstår også godt at det er noget med InvokeRequired, det læste jeg om på MSDN.microsoft.com, men nogle gange er deres eksempler altså ikke specielt lette at forstå.
Er der ikke en som kan komme med et meget simpelt eksempel som er lidt for dummy's! (Dummy = mig). I hvert fald lige i dette tilfælde...
Baggrunden er at du ikke kan tilgå GUI elementer fra andre tråde end den dit GUI kører på. Det har noget at gøre med den måde Windows og frameworket er bygget op på.
Når du så skal gøre "noget" med dine GUI elementer fra en anden tråd, er du nødt til at gøre det via Invoke metoden. Det denne metode reelt gør, er at sætte kaldet til den delegate, du giver den med, i kø til udførelse på GUI tråden. Invoke metoden returnerer så når det er udført. (Men der findes også en asynkron version).
Her er det korteste fungerende eksempel jeg lige kunne komme på.
using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms;
namespace WinFormThreadingTest { public class MyThreadAlteredForm : Form { private Label label = new Label(); public MyThreadAlteredForm(Program p) { p.StuffHappened += new EventHandler(p_StuffHappened); Text = "Form"; label.Text = "Before change"; Controls.Add(label); }
public class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Program p = new Program(); Form form = new MyThreadAlteredForm(p); ThreadPool.QueueUserWorkItem(p.ThreadRunMethod); Application.Run(form); }
public event EventHandler StuffHappened;
public void ThreadRunMethod(object state) { Thread.Sleep(1000); OnStuffHappened(EventArgs.Empty); }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.