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?
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)
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
cool, danke.
mit threads hab ich nicht hinbekommen, bekomme immer den gleichen fehler.
aber egal erstmal - **mit tasks läufts. **👍
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>
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.
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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 🙂
supi läuft jetzt und hab was dazugelernt ⚠
danke 👍