Forum: PC-Programmierung c# Threadübergreifende Zugriffe


von Peter (Gast)


Lesenswert?

Hallo NG,

ich "spiele" gerade ein wenig mit C#. Was ich gerne machen möchte:
Ein Button startet einen neuen Thread, der wiederum z.B. im Mainform 
irgendwas anstellt (denkbar wäre ein Statustext, oder ein 
Fortschrittsbalken.). Ich will das hier bewußt nicht über einen 
"BackgroundWorker" machen.

Jetzt habe ich mir schon ein kleines Testprojekt zusammengebastelt, wo 
ein Thread den Statusbalken im Mainfrom mit 100 Zufallswerten versorgt 
und ganz viel zählt, um auch etwas zu tun zu haben. Ich habe bewußt auf 
System.Threading.Thread.Sleep verzichtet, da ich nicht genau weiß, ob 
meine Frage damit zu tun hat :-)

Was mir jetzt gar nicht gefällt ist: Wenn ich das Fenster während des 
Laufenden Tasks bewege, dann scheint auch der Thread (Ihr wisst schon - 
der mit den vielen Zahlen) zu "schlafen". Ich würde gerne wollen, dass 
der Thread weiterarbeitet (der Balken springt) während ich das Fenster 
bewege, vergrößere oder was auch immer.

Wäre echt cool, wenn mir jemand sagen könnte, woran das hier liegt. Ich 
könnte mir vorstellen, dass der Thread an dem gleichen hängt, wie das 
Fenster (keine Ahnung). Wenn ja - wie kann man das ändern?

Hier mal mein Test:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Thread t = new Thread(new ThreadStart(aufgabe));
            t.Start();

        }

        private void aufgabe()
        {
            if (this.InvokeRequired == false)
            {
            }
            else
            {
                Del handler = DelegateMethod;
                Invoke(handler);
            }
        }

        public delegate void Del();

        public void DelegateMethod()
        {
            for (int i = 0; i < 100; i++)
            {
                Random r = new Random();
                progressBar1.Value = r.Next(100);
                for (int j = 0; j < 10000000; j++)
                {

                }
                Application.DoEvents();
            }
        }
    }
}

von Arc N. (arc)


Lesenswert?

> Wäre echt cool, wenn mir jemand sagen könnte, woran das hier liegt. Ich
> könnte mir vorstellen, dass der Thread an dem gleichen hängt, wie das
> Fenster (keine Ahnung). Wenn ja - wie kann man das ändern?

Das Problem ist, dass der Thread als erstes mit Invoke eine Methode 
aufruft, die genau dazu gedacht ist, UI-Updates im Hauptthread 
durchzuführen. Wenn der Hauptthread nun das Fenster neuzeichnet...
Dreh das ganze mal um
1
       public delegate void Del(int v);
2
3
        private void aufgabe() {
4
            Del handler = DelegateMethod;
5
            Random r = new Random();
6
            for (int i = 0; i < 100; i++) {
7
                Invoke(handler, new Object[] { r.Next(100) });
8
                for (int j = 0; j < 10000000; j++) {
9
                 }
10
            }
11
        }
12
        public void DelegateMethod(int v) {
13
            if (progressBar1 == null) return;
14
                progressBar1.Value = v;
15
                progressBar1.Update();
16
            }
17
        }

p.s. wenn das Programm beendet wird, bevor der Thread beendet ist/wird, 
wird es abstürzen (ObjectDisposedException)...

von Peter (Gast)


Lesenswert?

Vielen Dank Arc!

das funktioniert ja 100%. Ich bin echt begeistert. Vor allem denke ich, 
dass ich etwas gelernt habe :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.