Ich bin ein Forex Trading Roboter, und ich habe eine OutOfMemory Ausnahme nach einiger Zeit (ca. 2 Stunden) mit BlockingCollection. Ich habe im Grunde 1 Warteschlangenpaar Handel Diagramm, das in ein dict hinzugefügt werden:C# BlockingCollection verursacht nicht genügend Speicher
private Dictionary<string, BlockingCollection<tick>> tickQueues = new Dictionary<string, BlockingCollection<tick>>();
Ich überprüfe das Speicherabbild nach einer Stunde, und ich kann die folgenden Elemente sehen häufen sich:
Count Size(bytes) Inclusive Size
ThreadPoolWorkQueue+QueueSegment 22,951 24,236,256 40,316,868
QueueUserWorkItemCallback 689,838 13,796,760 16,081,272
TimerQueueTimer 11,160 713,772 2,355,736
ich habe einen Timer, der verantwortlich ist, Daten in die Warteschlange hinzuzufügen:
private void TickTimer_tick(object source, ElapsedEventArgs e) {
if (Monitor.TryEnter(LockTimerTick, GlobalSettings.APISleepDelayMSTick)) {
updateLockFailCount = 0;
try {
tick t = new tick(DateTime.Now, d.bid, d.ask);
lastBid = d.bid;
lastAsk = d.ask;
t.pair = Inst.pair;
//myTickQueue.TryAdd(t);
if (!myTickQueue.TryAdd(t)) {
functions.Logger.log("Error when adding Tick on Queue for " + Inst.pair+ " Maybe Queue is full", "SHMAPI", LOGLEVEL.WARN);
}
} catch (Exception E) {
functions.Logger.log("Error happened when refreshing tick data: " + E.Message, "SHMAPI", LOGLEVEL.ERROR);
} finally {
Monitor.Exit(LockTimerTick);
}
} else {
updateLockFailCount++;
int sev = LOGLEVEL.TRACE;
if (updateLockFailCount == 10) { sev = LOGLEVEL.DEBUG; }
if (updateLockFailCount==50) { sev = LOGLEVEL.WARN; }
if (updateLockFailCount % 100 == 0 && updateLockFailCount>=100) { sev = LOGLEVEL.ERROR; }
functions.Logger.log("Could not get lock to refresh tick data for symbol "+Symbol, "SHMAPI", sev);
}
}
Und schließlich meine Aufgabe, die die Q prüft:
Ich bin nicht wirklich sicher, warum ich OOM bin immer, aber es sieht ähnlich aus wie: http://blogs.microsoft.co.il/bnaya/2012/02/26/real-life-story-blocking-collection/ Aber ich bin nicht parallel hier ... Meine Queues leer sind, obwohl seit Wochen End-Markt geschlossen ist. Würde ein anderer Timer mit TryDequeue einen besseren Ansatz? Jeder Rat wäre willkommen!
Es sieht so aus, als ob Sie System.Timers.Timer verwenden? Wenn ja, in welchem Intervall? Wie lange dauert die Timer-Tick-Methode? Was ist der Wert von AutoReset für den Timer? –
Ich sehe kein offensichtliches Problem, aber ich habe nicht von dem Problem gehört, auf das Sie einen Link setzen. Aber ... wenn es ähnlich ist, versuchen Sie die Aufgabe mit TaskFactory.StartNew zu starten und setzen Sie die TaskCreationOptions auf LongRunning Außerdem: 1) Ihre Namenskonvention ist schrecklich, Sie können eine andere als Klasse, lokale Variable, Methode nicht sehen ... Versuchen Sie, es in mehr C# wie zu ändern: P 2) loszuwerden ToUpper() durch Setzen zusätzlicher Konstruktorparameter zu StringComparer.InvariantCultureIgnoreCase :) es wird sauberer und schneller sein – Carnifex
Hey, ich habe den Timer feuern alle 50ms .. Ich dachte eigentlich, dass mein Problem auf Timer-Ereignisse zurückzuführen sein könnte ... Ich werde es manuell versuchen und euch wissen lassen. FYI, Timer-Definition: TickTimer = new System.Timers.Timer(); TickTimer.Elapsed + = neuer ElapsedEventHandler (TickTimer_tick); TickTimer.Interval = GlobalSettings.APISleepDelayMSTick; // 50 MS TickTimer.AutoReset = true; // Lassen Sie den Timer wiederholte Ereignisse auslösen (true ist der Standardwert) TickTimer.Enabled = true; – bmigette