Autor Beitrag
Peter1000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60



BeitragVerfasst: Do 28.08.14 10:56 
Hallo,

bin Neu in c# und habe gerade einen Background-Worker erstellt.
Nun ist es so, dass dieser BackGroundWorker-Event-handler NUR dann freigibt, wenn ich eine Sleep-Funktion einbaue.

ich bräuchte aber was in der Art, das jedem Thread sozusagen eine bestimmte Zeit lang Rechnerzeit von einer Art Time-Scheduler zur verfügung
stellt.
Beispielsweise Thread1 laeuft 2 Millisekunden lang und wird dann für 2 Millisekunden unterbrochen. in dieser "Unterbrechungszeit" läuft dann
Thread2 2 Millisekunden lang usw.

Gibt's so was in C# ?

THX


Moderiert von user profile iconTh69: Topic aus C# - Die Sprache verschoben am Do 28.08.2014 um 13:16
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 28.08.14 11:31 
Wenn du genau das willst was du schreibst dann ist das kein C# Problem sondern ein Windows Problem. Für die genaue Zuteilung von Zeitresourcen zu einem Thread bräuchtest du ein Echtzeitbetriebssystem. Die Zuteilung der Laufzeit zu einem Thread ist eine explizite Betriebsystem aufgabe. Du bist ja nicht alleine im System mit deinem Prozess auch andere Prozesse haben entsprechende Anforderungen. Kein Prozess hat das Recht die Kontrolle über die Zuteilung selbst zu übernehmen. Wär auch Unfair den anderen Prozessen gegenüber ;)

Zitat:
Beispielsweise Thread1 laeuft 2 Millisekunden lang und wird dann für 2 Millisekunden unterbrochen.


Du kannst deinen Thread einfach für einen bestimmten Zeitraum schlafen legen (Thread.Sleep). Wer aber danach dran ist oder wann dein jetziger Thread nachdem der Schlaf beendet ist wieder dran kommt hast du keinen direkten Einfluß drauf. Das macht da OS möglichst fair über alle Prozesse.


Andererseits was ist der Sinn davon mehrere Threads zu haben die aber nacheinander laufen sollen. Warum ist das dann nicht einfach 1 Thread der die Aufgaben hintereinander ausführt?

Vielleicht erklärst du erst genauer was du vorhast.
Peter1000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60



BeitragVerfasst: Do 28.08.14 17:46 
Ja es kann eben bei aufwendigeren Threads sein, dass der Thread irgendwo relativ lange für etwas braucht das nicht vorhersehbar ist, und so der Sleep-Befehl relativ spät kommt. darum wäre mir ne Art präemtives Multitasking wesentlich lieber.
Aber es kommt mir so vor dass es nur ein kooperatives Multitasking gibt, in dem der ausführende Thread per guten Willen den Prozessor wieder abgeben kann. Das war beim uralt-Windows so.
Dass Windows nicht echtzeitfähig ist, d.h. keine klaren Zeitfenster garantiert ist mir schon klar und auch nicht das Problem.
Mir würde es ja genügen für einen Thread ein maximales Zeitfenster zu definieren. Wann Windows dem Thread dann wieder Zeit zur Verfügung stellt wäre ja erst mal egal.
Momentan muss man halt schauen, dass man an den richtigen Stelle im Thread immer wieder so "Sleeps" einbaut.

Gibt's das keine besser Lösung dafür?
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 28.08.14 18:07 
Zitat:
Gibt's das keine besser Lösung dafür?


Lösung für welches Problem?
Peter1000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60



BeitragVerfasst: Do 28.08.14 18:13 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Gibt's das keine besser Lösung dafür?


Lösung für welches Problem?


Dass ein aufwendiger Workerthread einmal länger den Prozessor nicht zurückgibt. Ist halt nicht so die elegante Lösung im Thread Haufen Sleeps einzubauen.
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Do 28.08.14 18:22 
Ich glaube es wäre einfacher dein Problem zu erkennen wenn du mal ein konkretes Beispiel nennst, was du nun tust und was das Endergebnis werden soll. So wie es aussieht bin ich nicht der einzige, der hier nicht ganz dein Problem versteht.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
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 28.08.14 18:31 
Zitat:
Dass ein aufwendiger Workerthread einmal länger den Prozessor nicht zurückgibt


Windows wird den Thread schon regelmäßig anhalten und andere laufen lassen. Wenn der Thread nichts wichtiges tut und weniger laufen soll dann reduziere die Priorität.
Da kannst du dann aber keinen Backgroundworker nehmen. Der benutzt irgendeinen Thread aus dem Threadpool. Gezielt da die Priorität zu setzen ist da schwierig bis unmöglich.

Also direkt die Thread Klasse verwenden, ThreadPool, TPL, PLINQ, Async/Await oder eins der anderen Threading Möglichkeiten die .Net bietet. Ohne Problem läßt sich da nix empfehlen.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Do 28.08.14 20:17 
Ich kann auch nur die TPL empfehlen, statt den (inzwischen etwas "angestaubten") BackgroundWorker.

Vielleicht ein kleines Beispiel:
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:
      var myTask = Task.Factory.StartNew(() =>
      {
        // LangeBerechnung
        int max = 100000;
        int count = 0;
        var rnd = new Random();
        for (int i = 0; i < max; i++)
        {
          var x = rnd.NextDouble();
          var y = rnd.NextDouble();
          if (x * x + y * y <= 1)
            count++;
        }
        return 4.0 * count / max;
      })
      .ContinueWith((x) =>
      {
        double pi = x.Result;
        this.Dispatcher.BeginInvoke(new Action(() => {
          Console.WriteLine(pi);
        }));
      });

Und natürlich kannst du auch in einem Task viele weitere Tasks starten. ( :arrow: www.entwickler-ecke.....php?p=676643#676643 )