Avatar billede lasserasch Juniormester
26. marts 2007 - 11:57 Der 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!

/Lasse
Avatar billede mh6000 Nybegynder
26. marts 2007 - 13:20 #1
i 1.1 skal du bruge begininvoke eller invoke metoden for at gøre det du ønsker ?
Jeg ved ikke om det stadig virker :-)
Avatar billede bjering Nybegynder
26. marts 2007 - 13:25 #2
Som han siger.

Søg efter eksempler på

Delegate og
InvokeRequired
Avatar billede mh6000 Nybegynder
26. marts 2007 - 13:36 #4
Avatar billede lasserasch Juniormester
26. marts 2007 - 13:42 #5
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);

        }

        void LoadWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
textbox1.Text = string1;
textbox2.Text = string2;

        }

        void LoadWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
              string1 = "testværdi 1. Kunne f.eks. være et resultat fra en SQL forespørgelse";

              string2 = "testværdi 2.";

        }



  private void button1_Click(object sender, EventArgs e)
        {
            LoadWorker1.RunWorkerAsync();
        }



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...

/Lasse
Avatar billede lasserasch Juniormester
26. marts 2007 - 13:44 #6
Lidt fejl i mit eksempel kan jeg se, men i forstår nok meningen alligevel....

/Lasse
Avatar billede driis Nybegynder
26. marts 2007 - 19:16 #7
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).

Jeg kan godt lige give et eksempel:
Avatar billede driis Nybegynder
26. marts 2007 - 19:30 #8
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);
        }

        void p_StuffHappened(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler(p_StuffHappened), sender, e);
            }
            else
            {
                label.Text = "Stuff has happened !";
            }
        }       
    }

    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);
        }

        protected virtual void OnStuffHappened(EventArgs e)
        {
            if (StuffHappened != null)
                StuffHappened(this, e);
        }
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester