Laden...

Thread mit Parametern starten

Erstellt von lolcore vor 2 Jahren Letzter Beitrag vor 2 Jahren 304 Views
lolcore Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren
Thread mit Parametern starten

ich habe folgenden code:


private static void LineReadedRUN1(){
    Console.WriteLine("IN LineReadedRUN1");
}

private static void LineReadedRUN2(String line){
    Console.WriteLine("IN LineReadedRUN2 " + line);
}

 public void NotifyLineObservers(String line){
    foreach (LineObserver obs in this.lineObservers){
    Thread t = new Thread(LineReadedRUN1);
    t.Start();
    t = new Thread(LineReadedRUN2(line)); // ######### Zeile 123  #############
    t.Start();
    }
 }

und bekomme beim kompilieren folgende meldung:

Fehler beim Buildvorgang.

"c:\tests\MyProj.proj" (Standardziel) (1) ->
(Build Ziel) ->
lolcoreIRC1.cs(123,9): error CS1502: Die beste Übereinstimmung für die überladene 'System.Threading.Thread.Thread(System.Threading.ThreadSt
art)'-Methode hat einige ungültige Argumente. [c:\tests\MyProj.proj]
lolcoreIRC1.cs(123,20): error CS1503: Argument '1': Konvertierung von 'void' in 'System.Threading.ThreadStart' nicht möglich. [c:\tests\MyP
roj.proj]

werd da nicht schlau draus. wie muss der aufruf lauten?

16.835 Beiträge seit 2008
vor 2 Jahren

Naja, die Parameter stimmen halt nicht, siehe Thread Klasse (System.Threading)
Du kannst bei Dir in Deiner Zeile 123 keine Methode mit Parametern verwenden, sondern musst das Delegat bekannt geben.

Ansonsten der Hinweis, dass man asynchrone Dinge wenn immer möglich mit Tasks umsetzen sollte, nich mit Threads.
Hier ist nicht nur die Programmierung viel viel einfacher, sondern auch in der Runtime i.d.R. effizienter.
Gibt nur ganz wenig Use Cases, in denen Threads wirklich die bessere / einzige Wahl ist.

Je nachdem könnte das so aussehen:


private static async Task Run(String line){
    Console.WriteLine("IN LineReadedRUN2 " + line);
}

 public async Task NotifyLineObservers(String line){
     await Run(line);
 }

Einstieg dazu: Task Parallel Library (TPL)

lolcore Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren

cool, danke.
mit threads hab ich nicht hinbekommen, bekomme immer den gleichen fehler.
aber egal erstmal - **mit tasks läufts. **👍

lolcore Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren

hm, zu früh gefreut. hab jetzt folgenden code:

namespace lolcoretest{
	
	
	
	class Test{
		public static void Main(string[] args){			
			
			Test t = new Test();
			//t.ProcessPaperbackBooks(PrintTitle);
			
			t.testit("hallo");
			
			int i = 0;
			while(true){
				i++;
				Console.WriteLine("logA: " + i);
				Thread.Sleep(2000);
			}
			
			
		}
		
	
		private static async Task Run(String line){
			int i = 0;
			while(true){
				
				i++;
				Console.WriteLine("logB:  " + i + " " + line);
				Thread.Sleep(3000);
			}
			
		}

		 public async Task testit(String line){
			 await Run(line);
		 }
		 
		 
	}	
}

die methoden laufen nicht gleichzeitig.

c:\tests\tests>dtest
logB: 1 hallo
logB: 2 hallo
logB: 3 hallo
logB: 4 hallo
logB: 5 hallo
logB: 6 hallo
^C
c:\tests\tests>

T
2.224 Beiträge seit 2008
vor 2 Jahren

Liegt daran, dass du auf den Task, von RUN in testit mit await wartest.
Dadurch wird erst der Task abgearbeitet und dann läuft erst deine Hauptschleife in Main.

Du müsstest nur auf den Task von testit warten und Run ohne await laufen lassen.
Dann laufen beide Schleifen.
Hier solltest du aber nicht mit Thread.Sleep in der Run Methode warten sondern mit Task.Delay

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.835 Beiträge seit 2008
vor 2 Jahren

hm, zu früh gefreut.

Das war ehrlich gesagt zu erwarten, so schnell wie Du eine "Lösung" hattest.
Warum? Man muss das Konzept verstehen, ansonsten wirst Du offensichtliche und versteckte Probleme bekommen.
Daher hab ich Dir auch die Doku dazu gepostet.

die methoden laufen nicht gleichzeitig.

Auch das zeigt den Verständnisfehler.
Asynchrone Programmierung und parallele Programmierung sind zwei verschiedene Konzepte - und async/await ist ein asynchrones Konzept.

Du müsstest nur auf den Task von testit warten und Run ohne await laufen lassen.

Nein, das sollte man nicht tun, da ansonsten zB auch Exceptions unterdrückt werden.
Um mehrere Tasks parallel auszuführen gibt es TzB ask.WhenAll.

lolcore Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren

ok nochmal von vorne:
ich möchte hier in meinem dummy zwei schleifen gleichzeitig (parallel) laufen lassen.


namespace lolcoretest{
	
	class Test{
		public static void Main(string[] args){			
			
			Test t = new Test();			
			t.testit("hallo");
			
			int i = 0;
			while(true){
				i++;
				Console.WriteLine("logA: " + i);
				Thread.Sleep(2000);
			}
			
			
		}
		
		//private static void Run(String line) 
		private static void Run(){  
			int i = 0;
			while(true){
				
				i++;
				//Console.WriteLine("logB: " + i + "#" + line); 
				Console.WriteLine("logB: " + i); 
				Thread.Sleep(3000);
			}
			
		}

		 public void testit(String line){
			 //Thread t = new Thread(Run(line)); // hier will ich line übergeben
			 Thread t = new Thread(Run);
			 t.Start();
		 }		 
	}	
}

konsolenausgabe:

c:\tests\tests>dtest
logA: 1
logB: 1
logA: 2
logB: 2
logA: 3
logB: 3
logA: 4
logA: 5
logB: 4
logA: 6
logB: 5
logA: 7
logA: 8
logB: 6
logA: 9
logB: 7
logA: 10
^C
c:\tests\tests>

das funktioniert soweit gut.
aber wenn ich dem thread line übergeben will (siehe kommentare) bekomme ich beim kompilieren die oben erwähnte fehlermeldung:
wie muss die zeile

Thread t = new Thread(Run(line)); 

richtig aussehen?
oder wie löse ich das problem mit tasks?
danke für eure geduld und hilfe.

P
441 Beiträge seit 2014
vor 2 Jahren

Wie Abt geschrieben hat, kannst du Tasks parallel laufen lassen mit Task.WhenAll:


Task t1 = RunFirst("...");
Task t2 = RunSecond("...");

await Task.WhenAll(t1, t2);

Ein Thread erwartet ein Delegate, da kannst du nicht einfach Parameter übergeben. Mit einem Delegaten (in dem Fall eine Action<T>) würde das so aussehen:


new Thread(() => RunFirst("..."));

Die Lösungen dazu hättest du mit den gegebenen Stichworten (Task.WhenAll und delegate) in der Doku und bei einer Google Recherche gefunden 🙂

lolcore Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren

supi läuft jetzt und hab was dazugelernt ⚠
danke 👍