Switched to Avalonia
This commit is contained in:
128
ParentAvalonia/ChildSession.cs
Normal file
128
ParentAvalonia/ChildSession.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using CommIpc;
|
||||
|
||||
namespace ParentAvalonia;
|
||||
|
||||
public sealed class ChildSession : NotifyBase, IAsyncDisposable
|
||||
{
|
||||
private readonly SemaphoreSlim _writeLock = new(1, 1);
|
||||
private string _status = "Starting";
|
||||
private double _progressPercent;
|
||||
private string? _currentWorkId;
|
||||
private bool _isConnected;
|
||||
|
||||
public int Id { get; }
|
||||
public string PipeName { get; }
|
||||
public string PipePath => CommIpc.PipeName.Describe(PipeName);
|
||||
|
||||
public NamedPipeServerStream Pipe { get; }
|
||||
public Process Process { get; }
|
||||
public CancellationTokenSource LifetimeCts { get; } = new();
|
||||
|
||||
public ObservableCollection<string> Logs { get; } = new();
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get => _isConnected;
|
||||
set
|
||||
{
|
||||
if (SetField(ref _isConnected, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(DisplayName));
|
||||
OnPropertyChanged(nameof(StatusLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set
|
||||
{
|
||||
if (SetField(ref _status, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(DisplayName));
|
||||
OnPropertyChanged(nameof(StatusLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName => $"Child {Id} ({(IsConnected ? "Connected" : "Disconnected")})";
|
||||
public string StatusLine => $"{Status} | Work: {(_currentWorkId ?? "-")}";
|
||||
|
||||
public double ProgressPercent
|
||||
{
|
||||
get => _progressPercent;
|
||||
set => SetField(ref _progressPercent, value);
|
||||
}
|
||||
|
||||
public string? CurrentWorkId
|
||||
{
|
||||
get => _currentWorkId;
|
||||
set
|
||||
{
|
||||
if (SetField(ref _currentWorkId, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(StatusLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ChildSession(int id, string pipeName, NamedPipeServerStream pipe, Process process)
|
||||
{
|
||||
Id = id;
|
||||
PipeName = pipeName;
|
||||
Pipe = pipe;
|
||||
Process = process;
|
||||
}
|
||||
|
||||
public async Task SendAsync(IpcFrame frame, CancellationToken cancellationToken)
|
||||
{
|
||||
await _writeLock.WaitAsync(cancellationToken);
|
||||
try
|
||||
{
|
||||
await IpcProtocol.WriteFrameAsync(Pipe, frame, cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddLog(string line)
|
||||
{
|
||||
// keep it from growing without bounds during prototyping
|
||||
if (Logs.Count > 2000)
|
||||
{
|
||||
Logs.RemoveAt(0);
|
||||
}
|
||||
Logs.Add(line);
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
LifetimeCts.Cancel();
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
if (!Process.HasExited)
|
||||
{
|
||||
Process.Kill(entireProcessTree: true);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try { Pipe.Dispose(); } catch { }
|
||||
try { Process.Dispose(); } catch { }
|
||||
try { LifetimeCts.Dispose(); } catch { }
|
||||
try { _writeLock.Dispose(); } catch { }
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user