115 lines
3.3 KiB
C#
115 lines
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MxGateway.Contracts.Proto;
|
|
using MxGateway.Worker.Sta;
|
|
|
|
namespace MxGateway.Worker.MxAccess;
|
|
|
|
public sealed class MxAccessStaSession : IDisposable
|
|
{
|
|
private readonly IMxAccessComObjectFactory factory;
|
|
private readonly IMxAccessEventSink eventSink;
|
|
private readonly StaRuntime staRuntime;
|
|
private StaCommandDispatcher? commandDispatcher;
|
|
private MxAccessSession? session;
|
|
private bool disposed;
|
|
|
|
public MxAccessStaSession()
|
|
: this(
|
|
new StaRuntime(),
|
|
new MxAccessComObjectFactory(),
|
|
new MxAccessBaseEventSink())
|
|
{
|
|
}
|
|
|
|
public MxAccessStaSession(
|
|
StaRuntime staRuntime,
|
|
IMxAccessComObjectFactory factory,
|
|
IMxAccessEventSink eventSink)
|
|
{
|
|
this.staRuntime = staRuntime ?? throw new ArgumentNullException(nameof(staRuntime));
|
|
this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
|
|
this.eventSink = eventSink ?? throw new ArgumentNullException(nameof(eventSink));
|
|
}
|
|
|
|
public Task<WorkerReady> StartAsync(
|
|
int workerProcessId,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
staRuntime.Start();
|
|
|
|
return staRuntime.InvokeAsync(
|
|
() =>
|
|
{
|
|
if (session is not null)
|
|
{
|
|
throw new InvalidOperationException("MXAccess COM session has already been created.");
|
|
}
|
|
|
|
session = MxAccessSession.Create(factory, eventSink);
|
|
commandDispatcher = new StaCommandDispatcher(
|
|
staRuntime,
|
|
new MxAccessCommandExecutor(session));
|
|
|
|
return session.CreateWorkerReady(workerProcessId);
|
|
},
|
|
cancellationToken);
|
|
}
|
|
|
|
public Task<MxCommandReply> DispatchAsync(StaCommand command)
|
|
{
|
|
if (commandDispatcher is null)
|
|
{
|
|
throw new InvalidOperationException("MXAccess COM session has not been started.");
|
|
}
|
|
|
|
return commandDispatcher.DispatchAsync(command);
|
|
}
|
|
|
|
public Task<IReadOnlyList<RegisteredServerHandle>> GetRegisteredServerHandlesAsync(
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (session is null)
|
|
{
|
|
throw new InvalidOperationException("MXAccess COM session has not been started.");
|
|
}
|
|
|
|
return staRuntime.InvokeAsync(
|
|
() => session.HandleRegistry.ServerHandles,
|
|
cancellationToken);
|
|
}
|
|
|
|
public Task<IReadOnlyList<RegisteredItemHandle>> GetRegisteredItemHandlesAsync(
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (session is null)
|
|
{
|
|
throw new InvalidOperationException("MXAccess COM session has not been started.");
|
|
}
|
|
|
|
return staRuntime.InvokeAsync(
|
|
() => session.HandleRegistry.ItemHandles,
|
|
cancellationToken);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (disposed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
commandDispatcher?.RequestShutdown();
|
|
|
|
if (session is not null)
|
|
{
|
|
staRuntime.InvokeAsync(() => session.Dispose()).GetAwaiter().GetResult();
|
|
}
|
|
|
|
staRuntime.Dispose();
|
|
disposed = true;
|
|
}
|
|
}
|