Laden...

Retriggerbarer Singlethread (aber nur mal)

Letzter Beitrag vor 2 Jahren 5 Posts 354 Views
Retriggerbarer Singlethread (aber nur mal)

Hallo,

bin auf der Suche nach einer speziellen Klasse, bzw. wir haben schon eine wollte aber wissen, vlt. gibt es sowas ja direkt im Framework.

Wir haben eine Action welche in bestimmten Intervallen aufgerufen werden muss. Glkeichzeitig brauche Ich auch einen externen Call, (z.b. WakeUp) der die Action, wenn Sie gerade nicht läuft, sofort startet. Dieser WakeUp kann mehrmals während die Action läuft aufgerufen werden, soll die Action danach aber nur ein mal noch Triggern. Diese soll aber sofort getriggert werden, und nicht erst wenn der timer wieder abgelaufen ist.

Ein Kollege von mit hat das vor Jahren recht kompliziert implementiert, nun wollte Ich Fragen gibts da direkt was oder muss ich das selber bauen. Möchte es auf jeden fall vereinfachen.

cSharp Projekte : https://github.com/jogibear9988

Schau dir doch die Timer-Klassen an?
Wenn es sofort triggern soll, stopst Du, setzt Du die Zeit auf 0 und startest wieder - oder nur auf 0 setzen, teste Mal aus, wie die sich dabei verhalten.
Ich nutze dafür aktuell den DispatcherTimer: Stop, Intervall setzen, Start

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Mein Kollege hatte mal das Programmiert:


    public class ThreadControl : IDisposable
    {
        private readonly object _wakeUpLock = new object();

        private readonly Action _workerThreadLoop;

        private readonly Timer _workerThreadWakeupTimer;

        private volatile bool _go;

        private volatile bool _stopThread;

        private Thread _workerThread;

        public WorkerThreadControl(Action workerThreadLoop)
        {
            _workerThreadLoop = workerThreadLoop;
            _workerThreadWakeupTimer = new Timer(state => WakeUpTimer(), null, -1, -1);
        }

        public void Dispose()
        {
            lock (_wakeUpLock)
            {
                _stopThread = true;
                Monitor.Pulse(_wakeUpLock);
            }

            if (_workerThread != null && !_workerThread.Join(5000))
            {
                _logger.Warn(GetType().Name, "Worker Thread stop did not respond...");
                _workerThread.Abort();
                _workerThread.Join();
                _workerThread = null;
            }
        }

        public void StartInternal()
        {
            if (_workerThread == null)
            {
                _workerThread = new Thread(() => _workerThreadLoop());
                _workerThread.Start();
            }
        }

        public void Wait(int timeout, out bool stop)
        {
            lock (_wakeUpLock)
            {
                while (!(_stopThread || _go))
                {
                    _workerThreadWakeupTimer.Change(timeout, -1); // start
                    Monitor.Wait(_wakeUpLock); // Lock is released while we’re waiting
                    _workerThreadWakeupTimer.Change(-1, -1); // stop
                }

                stop = _stopThread;
                _stopThread = false;
                _go = false;
            }
        }

        public void WakeUp()
        {
            Task.Factory.StartNew(() =>
            {
                lock (_wakeUpLock)
                {
                    _go = true;
                    Monitor.Pulse(_wakeUpLock);
                }
            });
        }

        private void WakeUpTimer()
        {
            lock (_wakeUpLock)
            {
                _go = true;
                Monitor.Pulse(_wakeUpLock);
            }
        }
    }

Ich denke das geht doch bestimmt einfacher.

Auch Thread.Abort sollte raus, geht in Netcore eh nicht mehr. Und denke wir brauchen auch keinen extra Thread

Nur über den ThreadingTimer, ich kann zwar die Zeit auf 0 setzen, aber was passiert wenn der Timer gerade läuft? Woher weiß ich wann ich die Zeit hochsetzen muss.

cSharp Projekte : https://github.com/jogibear9988

Dachte für dieses Problem gibts vlt. schon was im Framework (oder was in die Richtung).

Überlege ob es eine Möglichkeit gibt das ohne Lock zu implementieren...

cSharp Projekte : https://github.com/jogibear9988

was passiert wenn der Timer gerade läuft?

Indem Du es dir merkst.
Ein Boolean, Task für den aktuell laufenden Prozess bzw. null, ein ManualResetEvent, der den Zustand signalisiert, etc.
Je nachdem, wie Du damit umgehen willst, gibt's verschiedene Wege.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.