Laden...

If-Abfrage innerhalb eines Codeblockes bei vielen Threads

Erstellt von BlackMatrix vor 10 Jahren Letzter Beitrag vor 10 Jahren 986 Views
B
BlackMatrix Themenstarter:in
218 Beiträge seit 2012
vor 10 Jahren
If-Abfrage innerhalb eines Codeblockes bei vielen Threads

Hallo,

ich habe mich gefragt, wie die besser Alternative für folgendes Szenario aussieht.

Ich habe eine bestimmte Stelle im Code, die von mehreren Threads erreicht wird. Dann folgt ein Codeblock, der von nur genau einem Thread abgearbeitet werden darf (die anderen warten). Wurde dies durchgeführt wird eine Variable auf 'True' gesetzt. Nach einer unbekannten Zeit wird diese Variable wieder auf 'False' gesetzt. Müssen nun alle Threads jeweils immer überprüfen, ob die Variable 'False' geworden ist oder kann man das irgendwie auch anders lösen?

Ist das soweit verständlich?

LG BlackMatrix

3.430 Beiträge seit 2007
vor 10 Jahren

Hallo BlackMatrix,

schau dir mal das hier an: Multithreading in C#, Teil 11: Lock, Monitor, Mutex, Semaphore, SemaphoreSlim

Grüße
michlG

B
BlackMatrix Themenstarter:in
218 Beiträge seit 2012
vor 10 Jahren

Hallo michlG,

nun mir gehts nicht darum den Bereich für einige Threads zu sperren, sondern darum, ob denn wirklich jeder Thread diese If-Abfrage durchführen muss. Sehe ich das richtig, das die (bessere?) Alternative zu dem folgenden Codeausschnitt wäre den Codeabschnitt auch weiterhin zu locken, aber anstatt 100 Threads diese If-Abfrage durchlaufen zu lassen, einfach Enabled durch einen neuen, sehr hochpriorisieren Thread direkt die Arbeit auszuführen und wieder auf True zu setzen?


class Class
    {
        private Timer _timer = new Timer { AutoReset = false };
        private Random _random = new Random();
        public bool Enabled { get; private set; }

        public Class()
        {
            _timer.Elapsed += delegate { HandleElapsedEvent(); };
            HandleElapsedEvent();
        }

        private void HandleElapsedEvent()
        {
            Enabled = false;
            _timer.Interval = _random.Next();
            _timer.Start();
        }

        public void DoSomethingAccessedByManyThreads()
        {
            lock (this)//hier warten viele Threads
            {
                if (!Enabled)
                {
                    // Do something
                    Enabled = true;
                }
            }
        }

742 Beiträge seit 2005
vor 10 Jahren

Die If-Abfrage kostet doch nix, zumindest im Vergleich zu dem lock. Deshalb solltest du zweimal checken:


if (!IsEnabled)
{
   lock (lockObject)
   {
      if (!IsEnabled)
      {
         // Do something

         IsEnabled = true;
      }
   }
}

BTW: Die Namensbezeichnung und Überprüfung auf false ist eigenartig, würde das doch eher bennenen:

  • canDoX
  • isXAllowed
  • isYAvailable

o.ä.

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo BlackMatrix,

wenn es egal ist, welcher der Threads die Aktion im Then-Teil ausführt, warum schreibst du den Code nicht einfach in den HandleElapsedEvent-EventHandler. Dann kannst du dir die Variable IsEnabled ganz sparen.

Wenn die Aktion nicht parallel zu anderen Aktionen in den anderen Threads ausgeführt werden darf, musst du diese natürlich weiterhin synchronisieren.

Wie man das am geschicktesten macht, hängt von den Umständen ab. Diese sind mir aus deiner Beschreibung allerdings noch nicht ganz klar geworden.

herbivore