Avatar billede germann Nybegynder
16. februar 2004 - 15:40 Der er 5 kommentarer og
3 løsninger

Threads og synkronisering

Hej Alle,

Når jeg skriver til textboxen, så låser systemet. Er der nogle der kan hjælpe.

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.CompilerServices;

namespace SmartDeviceApplication5
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.MainMenu mainMenu1;
        public System.Windows.Forms.TextBox textBox1;
        Thread test;
        private ManualResetEvent allDone = new ManualResetEvent(true);

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();
            test = new Thread(new ThreadStart(proc));
            test.Start();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.textBox1 = new System.Windows.Forms.TextBox();
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(40, 64);
            this.textBox1.Multiline = true;
            this.textBox1.Size = new System.Drawing.Size(176, 56);
            this.textBox1.Text = "textBox1";
            //
            // Form1
            //
            this.Controls.Add(this.textBox1);
            this.Menu = this.mainMenu1;
            this.Text = "Form1";

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>

        static void Main()
        {
            Application.Run(new Form1());
        }


        public void proc()
        {
            while(true)
            {
                Monitor.Enter(textBox1);
                textBox1.Text = "Kasper";
                Monitor.Exit(textBox1);
            }

        }
    }
}
Avatar billede bennytordrup Nybegynder
16. februar 2004 - 15:51 #1
Du må ikke opdatere UI fra andre tråde end den, som har oprettet UI.

Du er nødt til at bruge Invoke for at gøre det.

Jeg har dog ikke umiddelbart noget kode på hvordan, for jeg er først selv ved at kigge på tråde.
Avatar billede nielsbrinch Nybegynder
16. februar 2004 - 16:42 #2
while(true) betyder den bliver ved med at skrive Kasper, i én uendelighed. Prøv uden while-løkken, så kommer der sikkert til at stå Kasper.
Avatar billede nielsbrinch Nybegynder
16. februar 2004 - 16:43 #3
benny.tordrup, jeg har lavet et program som helt fint opdaterer UI fra en anden tråd, end den der har oprettet UI'en. Jeg har ikke lavet nogle specielle krumspring.
Avatar billede pulsar Nybegynder
16. februar 2004 - 19:34 #4
nielsbrinch / germann:

Regel nr. 1 når man laver UI og tråde er at du ALDRIG må opdatere din UI med andre tråde end Main tråden.

I nogle tilfælde går det godt, men det vil helt sikkert lede til deadlock i længden.

Derfor skal man (som benny siger), invokere main tråden.

Det kan f.eks. gøres med en MethodInvoker:



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace WindowsApplication8
{

    public class Form1 : System.Windows.Forms.Form
    {
        private Thread t;
        private System.Windows.Forms.TextBox txttextBox1;
        private System.ComponentModel.Container components = null;
        private MethodInvoker methodInvoker = null;

        public Form1()
        {
   
            InitializeComponent();
            this.methodInvoker = new MethodInvoker(updateUI);
            this.HandleCreated += new EventHandler(Form1_HandleCreated);

        }

        public void proc()
        {
            for(int i = 0; i<1000; i++)
            {
                this.methodInvoker();
                Thread.Sleep(500);
            }
        }

        private void updateUI()
        {
            DateTime d = new DateTime();
            d = DateTime.Now;
            this.txttextBox1.Text = "Kasper - klokken er:  "+d.ToLongTimeString();
        }

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void Form1_HandleCreated(object sender, EventArgs e)
        {
            t = new Thread(new ThreadStart(proc));
            t.Start();
        }
}
}



germann:
Du skal ikke starte din tråd i constructoren, idet Formens Handle ikke er created endnu.
Og når Formens Handle ikke er created, så kan du ikke invokere UI tråden.


Bruge istedet Formen's HandleCreated event
Avatar billede pulsar Nybegynder
16. februar 2004 - 19:46 #5
Avatar billede germann Nybegynder
17. februar 2004 - 09:20 #6
Til pulsar, Problemmet er at compact framework ikke understøtter MethodInvoker.
Avatar billede pulsar Nybegynder
17. februar 2004 - 11:03 #7
germann:

Du skal stadig invokere UI tråden.

Brug istedet "Control.Invoke".


"You can update the user interface (UI) from a thread other than the UI thread by using Control.Invoke. This method executes a delegate in the control’s thread context on the UI thread. The .NET Compact Framework supports just one of the overloaded Control.Invoke methods from the full .NET Framework....."


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfmultithreadedapp.asp
Avatar billede germann Nybegynder
17. februar 2004 - 11:41 #8
TUSINDE TAK FOR HJÆLPEN. mvh Germann
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

IT-JOB

IT-Universitetet i København

CIO

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger AI forretningskonsulent i Ballerup

Politiets Efterretningstjeneste

IT Sikkerhedsarkitekt i PET