Autor Beitrag
Darter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 01.09.11 02:28 
Hey

Ich habe zu dem Thema ausführlich Google befragt, und auch einiges hilfreiches gefunen, wo unteranderem geraten wird, dass man sich eine Worker Klasse erstellen soll, was ich dann auch direkt gemacht hab.

Unteranderem erstelle ich ja eine WinForm, welche ja den Main Thread voll ausnutzt, und unteranderen wollte ich mit mehreren Threads eben verhindern, dass bei längeren Berechnungen, usw. die Form weiter beherrschbar bleibt.

Wie gesagt habe ich mir eine Worker Klasse erstellt, was ansich ja auch funktioniert, jedoch benötige ich nicht nur einen weiteren Thread, sondern mehrere.
Nun war meine Überlegung, ob ich an den Konstiktor der Worker Klasse einfach einen Funktionspointer übergebe, welche ich dann in der Worker-Methode Run ind Schleife immer wieder aufrufe, sodass ich mir nicht mehrere Worker Klassen erstellen muss, sondern jeweils immer nur eine Funktion, wo ich dann die Arbeit vollziehen lassen kann.

Hier mal meine Worker Klasse, vielleicht kann mir ja jemand bei der weiteren Vorgehensweise behilflich sein :-)

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadTest
{
    class WorkerThread
    {
        private Thread thread;
        private bool isRunning;

        public WorkerThread(int pFunc)
        {
            isRunning = true;
        }        

        public void StartThread() 
        {
            if (thread == null || (thread != null && !thread.IsAlive))
            {
                thread = new Thread(new ThreadStart(Run));
                thread.Start();                
            }
        }

        public void StopThread()
        {
            isRunning = false;
        }

        public Thread GetThread()
        {
            return thread;
        }

        private void Run()
        {
            while (isRunning)
            {
                Thread.Sleep(20);
            }
        }
    }
}


EDIT:
Zum besseren Verständniss noch etwas Pseydo Code :
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace ThreadTest
{
    class TestClass
    {
        public TestClass()
        {
            WorkerThread WThread = new WorkerThread(Pointer auf TestClassRun);
        }

        public void TestClassRun()
        {
            // mach was
        }
    }

    class WorkerThread
    {
        private Thread thread;
        private bool isRunning;
        // Pointer auf eine Funktion
        private int *pFunc;

        public WorkerThread(Pointer_auf_eine_Funktion)
        {
            // FUktionspointer dem privaten member zuweisen
            pFunc = Pointer_auf_eine_Funktion;
            isRunning = true;
        }

        public void StartThread()
        {
            if (thread == null || (thread != null && !thread.IsAlive))
            {
                thread = new Thread(new ThreadStart(Run));
                thread.Start();
            }
        }

        public void StopThread()
        {
            isRunning = false;
        }

        public Thread GetThread()
        {
            return thread;
        }

        private void Run()
        {
            while (isRunning)
            {
                //Pointerfunktion aufrufen
                pFunc();
                Thread.Sleep(20);
            }
        }
    }
}
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 01.09.11 09:59 
Hallo und :welcome:

mit Zeigern (Pointern) sollte man in C# nicht arbeiten (auch wenn es (teilweise) im unsafe-Modus funktioniert).

Das was du suchst, nennt sich "Delegate", s.a.mein Beitrag www.c-sharp-forum.de....php?p=647271#647271
Der Konstruktor der Thread-Klasse erwartet auch ein Delegate (namens ThreadStart), welcher dann intern die übergebene Methode aufruft.
Darter Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 01.09.11 17:54 
Hey.

Ich hab mir das nun angeschaut und versucht, aber ich schätze ich mache irgend etwas falsch ?!?

Hier meine Worker Thread Klasse :
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Test
{
    class WorkerThread
    {
        private Thread thread;
        private bool isRunning;
        private MyDelegate func;

        private delegate void MyDelegate();

        public WorkerThread(MyDelegate del)
        {
            func = del;
            isRunning = true;
        }       

        public void StartThread() 
        {
            if (thread == null || (thread != null && !thread.IsAlive))
            {
                thread = new Thread(new ThreadStart(Run));
                thread.Start();                
            }
        }

        public void StopThread()
        {
            isRunning = false;
        }

        public Thread GetThread()
        {
            return thread;
        }

        private void Run()
        {
            while (isRunning)
            {
                func();
            }
        }
    }
}


Hier die Klasse, vonder ich die WokrerThread klasse ansteuern will:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Test
{
    class Thread1
    {
        WorkerThread wThread = new WorkerThread(Run);

        public WorkerThread GetWThread()
        {
            return wThread;
        }

        public static void Run()
        {
            System.Console.Write("funktioniert\n");
            Thread.Sleep(500);
        }
    }
}


Und zu guterletztr noch die Klasse, wo alles seinen ANfang findet xD
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
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;

namespace Test
{
    public partial class Form1 : Form
    {
        private Thread1 thread = new Thread1();

        public Form1()
        {
            InitializeComponent();
        } 

        private void MIFileClose_Click(object sender, EventArgs e)
        {
            thread.GetWThread().StopThread();
            this.Close();
        }

        private void BStart_Click(object sender, EventArgs e)
        {
            this.BStart.Enabled = false;
            this.BStop.Enabled = true;
            /*
            ThreadStart pts = new ThreadStart(AoG.Program.SecontThread);
            Thread thread = new Thread(pts);
            thread.Start();
             */

            thread.GetWThread().StartThread();
        }

        private void BStop_Click(object sender, EventArgs e)
        {
            thread.GetWThread().StopThread();
            this.BStart.Enabled = true;
            this.BStop.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            thread.GetWThread().StopThread();
        }
    }
}


EDIT: hab die Fehlermeldungen vergessen ^^
ausblenden Quelltext
1:
Fehler  1  Inkonsistenter Zugriff: Feldtyp "Test.WorkerThread.MyDelegate" ist weniger zugreifbar als Feld "Test.WorkerThread.func"  C:\Users\....\documents\visual studio 2010\Projects\Test\Test\WorkerThread.cs  15  28  AoG					

ausblenden Quelltext
1:
Fehler  2  Inkonsistenter Zugriff: Parametertyp "Test.WorkerThread.MyDelegate" ist weniger zugreifbar als Methode "Test.WorkerThread.WorkerThread(Test.WorkerThread.MyDelegate)"  C:\Users\...\documents\visual studio 2010\Projects\Test\Test\WorkerThread.cs  19  16  AoG					
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 01.09.11 18:19 
ausblenden C#-Quelltext
1:
2:
3:
private MyDelegate func;

public WorkerThread(MyDelegate del)


Der Konstruktor ist wohl eher selten benutzbar. Zumindest wird dein Testcode deine Run Methode nicht als MyDelegate darstellen können wenn MyDelegate private ist. Um den Konstruktor auch public nutzen zu können müssen alle Typen die in der Signatur verwendet werden auch public sein.
Darter Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 01.09.11 18:50 
Hey.

Ok, klare Sache :-) Habs angepasst und funktioniert auch, aber ist das denn eine "saubere" Methode sowas zu machen ?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 01.09.11 20:24 
user profile iconDarter hat folgendes geschrieben Zum zitierten Posting springen:
aber ist das denn eine "saubere" Methode sowas zu machen ?
Bis jetzt sehe ich noch nichts, was überhaupt für deine WorkerThread-Klasse anstatt eines einfachen Threads oder Tasks spricht. Gerade durch die TPL geht der Trend imo weg von monolithischen Klassen, die sich um die komplette Parallelisierung kümmern hin zum Hintereinanderschalten einfacher Primitive.

_________________
>λ=