Laden...

Funktion mit zwei Parametern als Thread aufrufen

Erstellt von Skato vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.825 Views
S
Skato Themenstarter:in
46 Beiträge seit 2010
vor 13 Jahren
Funktion mit zwei Parametern als Thread aufrufen

Hallo,
ich würde gerne die Methode **transmit.fm(dataBuffer, datalenght); **
als Thread aufrufen, da das verarbeiten der Methode den restlichen Ablauf des Programms zu sehr verzögert. Daher würde ich es gerne vom rest abkoppeln.


using transmitter

namespace poster
{
public class IoPacket
    {

public void PostReceive()
        {

            try
            {

            transmit.fm(dataBuffer, datalength);

           }
.
.
.

Die Methode schaut so aus:


namespace poster
{
    
    class transmit
    {

 public static void fm(byte[] buffer, int bytesRead)
            
        { ... }
.
.
.

diese benötigt ein Bytearray und die Länge des Bytearrays als Integer.

Wie kann ich denn nun die Methode als Thread aufrufen und das Bytearray, Integer mitübergeben?

Parameterized Thread Start akzeptiert ja nur einen Parameter. Wie dann aber jetzt mit zweien?

Könnte mir bitte jemand dabei helfen?

mfg
skato

Edit: Methode nicht Funktion

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Parameterized Thread Start

das bedeutet auch selbst einen Thread erstellen was in den meisten Fällen schlechter ist als eine Thread aus dem ThreadPool zu verwenden.


byte[] dataBuffer= ...;
int datalenght= ...;

ThreadPool.QueueUserWorkItem(_ => transmit.fm(dataBuffer, datalenght));

Das funktionert aufgrund von Closures und so ist es auch der bevorzugte Weg eine Methode (nicht Funktion, da in C# alles Methoden sind) in einem (ThreadPool-) Thread auszuführen.
Ohne Closures siehe :rtfm: für QueueUserWorkItem.

Ab .net 4.0 bietet es sich an mit Tasks zu arbeiten, also


byte[] dataBuffer= ...;
int datalenght= ...;

Task.Factory.StartNew(() => transmit.fm(dataBuffer, datalenght));

BTW: Schau dir mal Namenskonventionen an.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo Skato,

Es gibt noch 2 andere Möglichkeiten

1: Ruf die transmit.fm(dataBuffer,datalength) in einer separaten Methode auf, und nicht direkt als Parameter der Thread.Start Methode. Deklarier dataBuffer,datalength lokal, dann kannst du die foo Methode im neuen Thread starten sofern dataBuffer,datalength den Zugriff zulassen.

private void foo()
{
    transmit.fm(dataBuffer, datalength);
}

Dann gibs 2 Möglichkeiten:
2: Erstell eine Hilfsmethode die du dann wie folg die foo(o) in der ParameterizedThreadStart aufrufst.

private void foo(object o)
{
    object[] oo = (object[])o;
    transmit.fm(oo[0], oo[1]);    //auf das richtige Casten
}

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

S
Skato Themenstarter:in
46 Beiträge seit 2010
vor 13 Jahren

Danke!

ich hab das jetzt so realisiert:

ThreadPool.QueueUserWorkItem(_ => transmit.fm(dataBuffer, datalenght));

Ich verwende übrigens das Net 3.5

Ist denn Thread Start so schlecht?

mfg
skato

3.971 Beiträge seit 2006
vor 13 Jahren

Geht auch super via Delegate.BeginInvoke. Einfach ein passendes Delegate erstellen, bzw. Action<> oder Func<> verwenden. Damit musst du nicht auf Typsicherheit verzichten und kannst auch wenn du brauchst einen Rückgabewert verwenden.

Schau dir bitte auch den Rückgabewert von BeginInvoke. Mit dem Waithandle hast du automatisch eine Thread.Join-Funktion.

Nachteil des ganzen, beim Aufruf von BeginInvoke solltest du später EndInvoke aufrufen. Besonders bei den MS Implementationen könnten sonst Speicherlecks entstehen.

Selber Threads zu erstellen, ist meist nur sinnvoll, wenn du die volle Kontrolle(Überwachung) über den Thread brauchst oder es sich um eine "lange" Aufgabe handelt. Wenn du nur etwas parallelisieren möchtest, ist die direkte Verwendung von Thread verkehrt, da allein das Erstellen des eines neuen Threads Ressourcen und Zeit verbraucht. Threadpool (BeginInvoke zählt auch dazu) verwenden existierende Threads, die nur drauf warten endlich mal was zu tun zu bekommen.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

S
Skato Themenstarter:in
46 Beiträge seit 2010
vor 13 Jahren

vielen Dank! das habe ich garnicht gewusst!

also sollte ich anstatt:

//Die TCP-Server (Listener) Threads für RM und FM starten

    
            //R1 Server Thread
            Thread R1_Server = new Thread(listener_R1.R1_main);
            R1_Server.Start(); //Thread starten

            Thread.Sleep(300);

            //R2 Server Thread
            Thread R2_Server = new Thread(listener_R2.R2_main); 
            R2_Server.Start(); //Thread starten

            Thread.Sleep(300);

            //RM Server Thread
            Thread FM_Server = new Threading.Thread(listener_fm.fm_main); 
            FM_Server.Start(); //Thread starten

            Thread.Sleep(300);

immer dies hier benutzen ?

ThreadPool.QueueUserWorkItem(_ => listener_R1.R1_main());

Die Methoden laufen ja eh in einer Dauerschleife und werden erst beendet wenn das Programm geschlossn wird. Es geht halt hauptsächlich um Paralellisierung.

mfg
skato

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Skato,

in dem Fall laufen die Threads (relativ) lange und der Vorteil der geringeren Startzeit fällt nicht ins Gewicht. Dagegen entsteht der Nachteil, dass du ThreadPool-Threads, die vielleicht später für andere Aufgaben benötigt werden, eben relativ lange blockierst. Im konkreten Fall solltest du also bei normalen Threads bleiben.

herbivore

S
Skato Themenstarter:in
46 Beiträge seit 2010
vor 13 Jahren

vielen dank! das ist gut zu wissen