- fix: memory leak part 1
This commit is contained in:
87
Nebula.Launcher/Services/InstanceRunningContainer.cs
Normal file
87
Nebula.Launcher/Services/InstanceRunningContainer.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nebula.Launcher.Models;
|
||||
using Nebula.Launcher.ProcessHelper;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
using Nebula.Shared;
|
||||
using Nebula.Shared.Services;
|
||||
|
||||
namespace Nebula.Launcher.Services;
|
||||
|
||||
[ServiceRegister]
|
||||
public sealed class InstanceRunningContainer(PopupMessageService popupMessageService, DebugService debugService)
|
||||
{
|
||||
private readonly InstanceKeyPool _keyPool = new();
|
||||
private readonly Dictionary<InstanceKey, ProcessRunHandler> _processCache = new();
|
||||
private readonly Dictionary<InstanceKey, ContentLogConsumer> _contentLoggerCache = new();
|
||||
private readonly Dictionary<ProcessRunHandler, InstanceKey> _keyCache = new();
|
||||
|
||||
public Action<InstanceKey, bool>? IsRunningChanged;
|
||||
|
||||
public InstanceKey RegisterInstance(IProcessStartInfoProvider provider)
|
||||
{
|
||||
var id = _keyPool.Take();
|
||||
|
||||
var currentContentLogConsumer = new ContentLogConsumer();
|
||||
var logBridge = new DebugLoggerBridge(debugService.GetLogger("PROCESS_"+id.Id));
|
||||
var logContainer = new ProcessLogConsumerCollection();
|
||||
logContainer.RegisterLogger(currentContentLogConsumer);
|
||||
logContainer.RegisterLogger(logBridge);
|
||||
|
||||
var handler = new ProcessRunHandler(provider, logContainer);
|
||||
handler.OnProcessExited += OnProcessExited;
|
||||
|
||||
_processCache[id] = handler;
|
||||
_contentLoggerCache[id] = currentContentLogConsumer;
|
||||
_keyCache[handler] = id;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public void Popup(InstanceKey instanceKey)
|
||||
{
|
||||
if(!_contentLoggerCache.TryGetValue(instanceKey, out var handler))
|
||||
return;
|
||||
|
||||
handler.Popup(popupMessageService);
|
||||
}
|
||||
|
||||
public void Run(InstanceKey instanceKey)
|
||||
{
|
||||
if(!_processCache.TryGetValue(instanceKey, out var process))
|
||||
return;
|
||||
|
||||
process.Start();
|
||||
IsRunningChanged?.Invoke(instanceKey, true);
|
||||
}
|
||||
|
||||
public void Stop(InstanceKey instanceKey)
|
||||
{
|
||||
if(!_processCache.TryGetValue(instanceKey, out var process))
|
||||
return;
|
||||
|
||||
process.Stop();
|
||||
}
|
||||
|
||||
public bool IsRunning(InstanceKey instanceKey)
|
||||
{
|
||||
return _processCache.ContainsKey(instanceKey);
|
||||
}
|
||||
|
||||
private void RemoveProcess(ProcessRunHandler handler)
|
||||
{
|
||||
if(handler.Disposed) return;
|
||||
|
||||
var key = _keyCache[handler];
|
||||
IsRunningChanged?.Invoke(key, false);
|
||||
_processCache.Remove(key);
|
||||
_keyCache.Remove(handler);
|
||||
_contentLoggerCache.Remove(key);
|
||||
}
|
||||
|
||||
private void OnProcessExited(ProcessRunHandler obj)
|
||||
{
|
||||
obj.OnProcessExited -= OnProcessExited;
|
||||
RemoveProcess(obj);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user