Ich sage dies als Reaktion auf eine Menge Fragen: Vergessen Sie nicht, dass der (verwaltete) Quellcode für das Framework verfügbar ist. Sie können dieses Tool verwenden, um es zu bekommen: Leider http://www.codeplex.com/NetMassDownloader
, in diesem speziellen Fall eine Menge von der Implementierung in nativen Code, so dass Sie nicht um es zu betrachten bekommen ...
Sie verwende definitiv Pool-Threads und nicht einen Thread pro Timer.
Der Standard Weg, um eine große Sammlung von Timern zu implementieren (was der Kernel tut es intern, und ich würde vermuten, ist indirekt, wie Ihre große Sammlung von Timern endet) ist die Liste nach Zeit sortiert - bis - Ablauf - das System muss sich also nur darum kümmern, den nächsten Timer zu prüfen, der abläuft, nicht die ganze Liste.
Grob gesagt gibt dies O (log n) zum Starten eines Timers und O (1) zum Verarbeiten von laufenden Timern.
Bearbeiten: Just in Jeff Richters Buch gesucht. Er sagt (von Threading.Timer), dass es einen einzigen Thread für alle Timer-Objekte verwendet, dieser Thread weiß, wann der nächste Timer (d. H. Wie oben) fällig ist, und ruft ThreadPool.QueueUserWorkItem für die Rückrufe entsprechend auf. Dies hat zur Folge, dass, wenn Sie die Bearbeitung eines Callbacks für einen Timer nicht beenden, bevor der nächste fällig ist, dass Ihr Callback erneut in einem anderen Poolthread eintritt. Zusammenfassend bezweifle ich, dass Sie ein großes Problem mit vielen Timern sehen werden, aber Sie könnten die Erschöpfung des Thread-Pools erleiden, wenn eine große Anzahl von ihnen auf denselben Timer feuert und/oder ihre Callbacks langsam laufen.
Eine Prioritätswarteschlange wäre wahrscheinlich effizienter als eine sortierte Liste, es sei denn, alle Timer werden am Anfang in Bulk hinzugefügt, dann sortiert und später nicht mehr hinzugefügt. – RAL
Sicher - "eine nach Zeit bis zum Ablauf sortierte Liste" könnte sicherlich eine Art Prioritätswarteschlange sein - ich wollte damit nicht "eine Liste implizieren, über die eine Sortieroperation ausgeführt wurde" –
Ich habe gerade einige Zeit damit verbracht über den Code in der SSCI. Beachten Sie, dass sich der .NET ThreadPool seit der Veröffentlichung von Rotor immens verändert hat. Daher ist es durchaus möglich, dass sich auch der System.Threading.Timer immens verändert hat. Tatsächlich wurden Timer in .NET 1.1 schlecht gebrochen und nur in .NET 2.0 behoben. Wie auch immer, in Rotor werden die Timer in einer verketteten Liste gehalten und durch einen dedizierten Timer ausgelöst. Es gibt einen Timer-Thread für die gesamte Laufzeit (auch über mehrere App-Domänen hinweg). –