Innovenergy_trunk/csharp/Lib/Utils/WIP/ObservableProcess.cs

56 lines
1.8 KiB
C#

using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using CliWrap;
namespace InnovEnergy.Lib.Utils.WIP;
using Data = IReadOnlyList<Byte>;
public class ObservableProcess
{
private readonly Command _Command;
private readonly CancellationTokenSource _Kill = new CancellationTokenSource();
private readonly CancellationTokenSource _Interrupt = new CancellationTokenSource();
private readonly ObserverPipeSource _StdIn = new ObserverPipeSource();
private readonly ReadablePipeTarget _StdOut = new ReadablePipeTarget();
private readonly ReadablePipeTarget _StdErr = new ReadablePipeTarget();
public IObserver<Data> StdIn => _StdIn;
private readonly Subject<Int32> _Pid = new Subject<Int32>();
private readonly Subject<Int32> _ExitCode = new Subject<Int32>();
public Task<Int32> Pid { get; }
public Task<Int32> ExitCode { get; }
public Task<Data> Read(Int32 nBytes) => _StdOut.Read(nBytes);
public ObservableProcess(Command command)
{
_Command = command;
Pid = _Pid.ToTask();
ExitCode = _ExitCode.ToTask();
}
public void Start()
{
var commandTask = _Command
.WithStandardInputPipe(_StdIn)
.WithStandardOutputPipe(_StdOut)
.WithStandardErrorPipe(_StdErr)
.ExecuteAsync(_Kill.Token, _Interrupt.Token);
_Pid.OnNext(commandTask.ProcessId);
commandTask.Task
.ToObservable()
.Select(t => t.ExitCode)
.Subscribe(_ExitCode);
}
public void Kill() => _Kill.Cancel();
public void Interrupt() => _Interrupt.Cancel();
}