mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-17 03:15:47 +02:00
94 lines
3.1 KiB
C#
94 lines
3.1 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Timers;
|
|
using CefSharp;
|
|
using CefSharp.WinForms;
|
|
using TweetDuck.Core.Controls;
|
|
using Timer = System.Timers.Timer;
|
|
|
|
namespace TweetDuck.Core.Other.Management{
|
|
sealed class MemoryUsageTracker : IDisposable{
|
|
private const int IntervalMemoryCheck = 60000*30; // 30 minutes
|
|
private const int IntervalCleanupAttempt = 60000*5; // 5 minutes
|
|
|
|
private readonly string script;
|
|
private readonly Timer timer;
|
|
private FormBrowser owner;
|
|
private IBrowser browser;
|
|
|
|
private long threshold;
|
|
private bool needsCleanup;
|
|
|
|
public MemoryUsageTracker(string cleanupFunctionName){
|
|
this.script = $"window.{cleanupFunctionName} && window.{cleanupFunctionName}()";
|
|
|
|
this.timer = new Timer{ Interval = IntervalMemoryCheck };
|
|
this.timer.Elapsed += timer_Elapsed;
|
|
}
|
|
|
|
public void Start(ChromiumWebBrowser control, int thresholdMB){
|
|
Stop();
|
|
|
|
this.owner = (FormBrowser)control.Parent; // TODO ugly
|
|
this.browser = control.GetBrowser();
|
|
this.threshold = thresholdMB*1024L*1024L;
|
|
this.timer.SynchronizingObject = owner;
|
|
this.timer.Start();
|
|
}
|
|
|
|
public void Stop(){
|
|
timer.Stop();
|
|
timer.SynchronizingObject = null;
|
|
owner = null;
|
|
browser = null;
|
|
SetNeedsCleanup(false);
|
|
}
|
|
|
|
public void Dispose(){
|
|
timer.SynchronizingObject = null;
|
|
timer.Dispose();
|
|
owner = null;
|
|
browser = null;
|
|
}
|
|
|
|
private void SetNeedsCleanup(bool value){
|
|
if (needsCleanup != value){
|
|
needsCleanup = value;
|
|
timer.Interval = value ? IntervalCleanupAttempt : IntervalMemoryCheck; // restarts timer
|
|
}
|
|
}
|
|
|
|
private void timer_Elapsed(object sender, ElapsedEventArgs e){
|
|
if (owner == null || browser == null){
|
|
return;
|
|
}
|
|
|
|
if (needsCleanup){
|
|
if (!owner.ContainsFocus){
|
|
using(IFrame frame = browser.MainFrame){
|
|
frame.EvaluateScriptAsync(script).ContinueWith(task => {
|
|
JavascriptResponse response = task.Result;
|
|
|
|
if (response.Success && (response.Result as bool? ?? false)){
|
|
SetNeedsCleanup(false);
|
|
owner.InvokeAsyncSafe(() => owner.TriggerAnalyticsEvent(Analytics.AnalyticsFile.Event.GCReload));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
try{
|
|
using(Process process = BrowserProcesses.FindProcess(browser)){
|
|
if (process?.PrivateMemorySize64 > threshold){
|
|
SetNeedsCleanup(true);
|
|
}
|
|
}
|
|
}catch{
|
|
// ignore I guess?
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|