Добавление IDisposable
This commit is contained in:
@@ -31,7 +31,21 @@ namespace Example.Backend
|
||||
|
||||
public async Task AsyncTest(CancellationToken token)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5), token);
|
||||
Console.WriteLine("Async Test");
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
Console.WriteLine("Waiting canceled");
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("Waiting...");
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine("Waited until the end");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Example.Shared;
|
||||
@@ -18,5 +19,10 @@ namespace Example.Backend
|
||||
// throw new Exception("The method or operation is not implemented.");
|
||||
return new Page {Text = text};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Console.WriteLine("Dispose printer with name {0}", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,11 @@ namespace Example.Frontend
|
||||
await Task.Yield();
|
||||
return new ClientBasedPage();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientBasedPage : IPage
|
||||
|
||||
+37
-22
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Example.Frontend;
|
||||
using Example.Shared;
|
||||
using mROA.Codegen;
|
||||
@@ -44,36 +45,50 @@ class Program
|
||||
|
||||
//правильный порядок команд 8-5-10-7
|
||||
var printer = factory.Create("Test");
|
||||
Console.WriteLine("Printer created");
|
||||
Thread.Sleep(100);
|
||||
using (var disposingPrinter = printer.Value)
|
||||
{
|
||||
Console.WriteLine("Printer created");
|
||||
Thread.Sleep(100);
|
||||
|
||||
var name = printer.Value.GetName();
|
||||
Console.WriteLine("Printer name : {0}", name);
|
||||
|
||||
Thread.Sleep(100);
|
||||
var name = disposingPrinter.GetName();
|
||||
Console.WriteLine("Printer name : {0}", name);
|
||||
|
||||
factory.Register(new SharedObject<IPrinter>(new ClientBasedPrinter()));
|
||||
Console.WriteLine("Registered printer");
|
||||
Thread.Sleep(100);
|
||||
Thread.Sleep(100);
|
||||
|
||||
factory.Register(new SharedObject<IPrinter>(new ClientBasedPrinter()));
|
||||
Console.WriteLine("Registered printer");
|
||||
Thread.Sleep(100);
|
||||
|
||||
|
||||
var registred = factory.GetFirstPrinter();
|
||||
Console.WriteLine("First printer");
|
||||
Thread.Sleep(100);
|
||||
var registred = factory.GetFirstPrinter();
|
||||
Console.WriteLine("First printer");
|
||||
Thread.Sleep(100);
|
||||
|
||||
Console.WriteLine(registred.Value);
|
||||
Console.WriteLine("Collecting all printers");
|
||||
var names = factory.CollectAllNames();
|
||||
Thread.Sleep(100);
|
||||
Console.WriteLine(registred.Value);
|
||||
Console.WriteLine("Collecting all printers");
|
||||
var names = factory.CollectAllNames();
|
||||
Thread.Sleep(100);
|
||||
|
||||
Console.WriteLine(string.Join(", ", names));
|
||||
Console.WriteLine(string.Join(", ", names));
|
||||
|
||||
var page = printer.Value.Print("Test Page", new CancellationToken()).GetAwaiter().GetResult();
|
||||
Console.WriteLine("Page printed");
|
||||
var data = page.Value.GetData();
|
||||
Console.WriteLine("Data : {0}", Encoding.UTF8.GetString(data));
|
||||
var page = disposingPrinter.Print("Test Page", new CancellationToken()).GetAwaiter().GetResult();
|
||||
Console.WriteLine("Page printed");
|
||||
var data = page.Value.GetData();
|
||||
Console.WriteLine("Data : {0}", Encoding.UTF8.GetString(data));
|
||||
}
|
||||
|
||||
// var loadSingleton = context.GetSingleObject(typeof(ILoadTest)) as ILoadTest;
|
||||
|
||||
var loadSingleton = context.GetSingleObject(typeof(ILoadTest)) as ILoadTest;
|
||||
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var token = cts.Token;
|
||||
var t = Task.Run(async () => await loadSingleton!.AsyncTest(token));
|
||||
|
||||
Thread.Sleep(5000);
|
||||
cts.Cancel();
|
||||
Console.WriteLine($"Token state {cts.Token.IsCancellationRequested}");
|
||||
Console.ReadKey();
|
||||
//
|
||||
// const int iterations = 10000;
|
||||
// var timer = Stopwatch.StartNew();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Implementation;
|
||||
@@ -6,7 +7,7 @@ using mROA.Implementation.Attributes;
|
||||
namespace Example.Shared
|
||||
{
|
||||
[SharedObjectInterface]
|
||||
public interface IPrinter
|
||||
public interface IPrinter : IDisposable
|
||||
{
|
||||
string GetName();
|
||||
Task<SharedObject<IPage>> Print(string text, CancellationToken cancellationToken);
|
||||
|
||||
@@ -233,6 +233,9 @@ namespace mROA.Codegen
|
||||
|
||||
public MethodInfo GetMethod(int id)
|
||||
{{
|
||||
if (id == -1)
|
||||
return typeof(IDisposable).GetMethod(""Dispose"");
|
||||
|
||||
if (_methods.Count <= id)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace mROA.Implementation.Backend
|
||||
public ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository,
|
||||
IRepresentationModule representationModule)
|
||||
{
|
||||
Console.WriteLine(command.GetType().Name);
|
||||
|
||||
if (_cancellationRepo is null)
|
||||
throw new NullReferenceException("Method repository was not defined");
|
||||
|
||||
@@ -30,6 +32,19 @@ namespace mROA.Implementation.Backend
|
||||
if (contextRepository is null)
|
||||
throw new NullReferenceException("Context repository was not defined");
|
||||
|
||||
if (command is CancelRequest)
|
||||
{
|
||||
Console.WriteLine("Final cancelling request");
|
||||
var cts = _cancellationRepo.GetCancellation(command.Id);
|
||||
cts.Cancel();
|
||||
_cancellationRepo.FreeCancelation(command.Id);
|
||||
return new FinalCommandExecution
|
||||
{
|
||||
Id = command.Id,
|
||||
CommandId = command.CommandId
|
||||
};
|
||||
}
|
||||
|
||||
var currentCommand = _methodRepo.GetMethod(command.CommandId);
|
||||
if (currentCommand == null)
|
||||
throw new Exception($"Command {command.CommandId} not found");
|
||||
@@ -48,7 +63,14 @@ namespace mROA.Implementation.Backend
|
||||
return ExecuteAsync(currentCommand, context, parameter, command, _cancellationRepo,
|
||||
representationModule);
|
||||
|
||||
return Execute(currentCommand, context, parameter, command);
|
||||
var result = Execute(currentCommand, context, parameter, command);
|
||||
|
||||
if (command.CommandId == -1)
|
||||
{
|
||||
contextRepository.ClearObject(command.ObjectId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ICommandExecution Execute(MethodInfo currentCommand, object context, object? parameter,
|
||||
@@ -57,9 +79,10 @@ namespace mROA.Implementation.Backend
|
||||
try
|
||||
{
|
||||
var finalResult = currentCommand.Invoke(context, parameter is null
|
||||
? new object[0]
|
||||
? Array.Empty<object>()
|
||||
: new[]
|
||||
{ parameter });
|
||||
|
||||
return new TypedFinalCommandExecution
|
||||
{
|
||||
CommandId = command.CommandId, Result = finalResult,
|
||||
@@ -77,13 +100,14 @@ namespace mROA.Implementation.Backend
|
||||
}
|
||||
}
|
||||
|
||||
private static ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
|
||||
private ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
|
||||
ICallRequest command, ICancellationRepository cancellationRepository,
|
||||
IRepresentationModule representationModule)
|
||||
{
|
||||
var tokenSource = new CancellationTokenSource();
|
||||
cancellationRepository.RegisterCancellation(command.Id, tokenSource);
|
||||
var token = tokenSource.Token;
|
||||
token.Register(() => Console.WriteLine($"Cancellation requested check {command.Id}"));
|
||||
try
|
||||
{
|
||||
var result = (Task)currentCommand.Invoke(context, parameter is null
|
||||
@@ -94,11 +118,16 @@ namespace mROA.Implementation.Backend
|
||||
|
||||
result.ContinueWith(_ =>
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var payload = new FinalCommandExecution
|
||||
{
|
||||
Id = command.Id,
|
||||
CommandId = command.CommandId
|
||||
};
|
||||
_cancellationRepo.FreeCancelation(command.Id);
|
||||
|
||||
var multiClientOwnershipRepository =
|
||||
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
|
||||
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
|
||||
@@ -121,7 +150,7 @@ namespace mROA.Implementation.Backend
|
||||
}
|
||||
}
|
||||
|
||||
private static ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
|
||||
private ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
|
||||
ICallRequest command, ICancellationRepository cancellationRepository,
|
||||
IRepresentationModule representationModule)
|
||||
{
|
||||
@@ -147,6 +176,8 @@ namespace mROA.Implementation.Backend
|
||||
CommandId = command.CommandId,
|
||||
Type = finalResult?.GetType()
|
||||
};
|
||||
_cancellationRepo.FreeCancelation(command.Id);
|
||||
|
||||
var multiClientOwnershipRepository =
|
||||
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
|
||||
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
|
||||
@@ -18,9 +19,18 @@ namespace mROA.Implementation
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public int CommandId { get; set; }
|
||||
public int ObjectId { get; set; } = -1;
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public Type? ParameterType { get; set; }
|
||||
|
||||
public object? Parameter { get; set; }
|
||||
}
|
||||
|
||||
public class CancelRequest : ICallRequest
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int CommandId { get; set; } = -2;
|
||||
public int ObjectId { get; set; } = -2;
|
||||
public object? Parameter { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Backend;
|
||||
@@ -53,45 +54,68 @@ namespace mROA.Implementation.Frontend
|
||||
throw new NullReferenceException("Method repository is null.");
|
||||
|
||||
await Task.Yield();
|
||||
|
||||
var multiClientOwnershipRepository = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
|
||||
|
||||
var multiClientOwnershipRepository =
|
||||
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
|
||||
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var request =
|
||||
_representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
|
||||
Console.WriteLine("Waiting for request...");
|
||||
var tokenSource = new CancellationTokenSource();
|
||||
var token = tokenSource.Token;
|
||||
var defaultRequest =
|
||||
_representationModule!.GetMessageAsync<DefaultCallRequest>(
|
||||
messageType: MessageType.CallRequest, token: token);
|
||||
var cancelRequest =
|
||||
_representationModule!.GetMessageAsync<CancelRequest>(
|
||||
messageType: MessageType.CancelRequest, token: token);
|
||||
|
||||
// Console.WriteLine("Executing {0}", request.Id);
|
||||
|
||||
if (request.Parameter is not null)
|
||||
Task.WaitAny(defaultRequest, cancelRequest);
|
||||
|
||||
Console.WriteLine("Request received");
|
||||
|
||||
if (cancelRequest.IsCompleted)
|
||||
{
|
||||
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
|
||||
.ParameterType;
|
||||
|
||||
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
|
||||
Console.WriteLine("Cancelling request");
|
||||
var req = cancelRequest.Result;
|
||||
tokenSource.Cancel();
|
||||
_executeModule.Execute(req, _contextRepository, _representationModule);
|
||||
}
|
||||
|
||||
var result = _executeModule.Execute(request, _contextRepository, _representationModule);
|
||||
|
||||
var resultType = MessageType.Unknown;
|
||||
|
||||
switch (result)
|
||||
else
|
||||
{
|
||||
case FinalCommandExecution:
|
||||
resultType = MessageType.FinishedCommandExecution;
|
||||
break;
|
||||
case AsyncCommandExecution:
|
||||
resultType = MessageType.AsyncCommandExecution;
|
||||
break;
|
||||
case ExceptionCommandExecution:
|
||||
resultType = MessageType.ExceptionCommandExecution;
|
||||
break;
|
||||
}
|
||||
tokenSource.Cancel();
|
||||
var request = defaultRequest.Result;
|
||||
|
||||
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
|
||||
if (request.Parameter is not null)
|
||||
{
|
||||
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
|
||||
.ParameterType;
|
||||
|
||||
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
|
||||
}
|
||||
|
||||
var result = _executeModule.Execute(request, _contextRepository, _representationModule);
|
||||
|
||||
var resultType = MessageType.Unknown;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case FinalCommandExecution:
|
||||
resultType = MessageType.FinishedCommandExecution;
|
||||
break;
|
||||
case AsyncCommandExecution:
|
||||
resultType = MessageType.AsyncCommandExecution;
|
||||
break;
|
||||
case ExceptionCommandExecution:
|
||||
resultType = MessageType.ExceptionCommandExecution;
|
||||
break;
|
||||
}
|
||||
|
||||
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -99,6 +123,5 @@ namespace mROA.Implementation.Frontend
|
||||
multiClientOwnershipRepository?.FreeOwnership();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -86,10 +86,11 @@ namespace mROA.Implementation
|
||||
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
|
||||
|
||||
var message = _serialization.Deserialize<NetworkMessage>(localSpan.Span);
|
||||
_messageBuffer.Add(message!);
|
||||
Console.WriteLine($"Received Message {message.SchemaId} - {message.Id}");
|
||||
_messageBuffer.Add(message);
|
||||
_currentReceiving = Task.Run(async () => await GetNextMessage());
|
||||
|
||||
return message!;
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Threading;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.CommandExecution;
|
||||
@@ -7,7 +8,7 @@ using mROA.Implementation.CommandExecution;
|
||||
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public abstract class RemoteObjectBase
|
||||
public abstract class RemoteObjectBase : IDisposable
|
||||
{
|
||||
private readonly int _id;
|
||||
private readonly IRepresentationModule _representationModule;
|
||||
@@ -20,7 +21,7 @@ namespace mROA.Implementation
|
||||
|
||||
public int Id => _id;
|
||||
public int OwnerId => _representationModule.Id;
|
||||
|
||||
|
||||
protected async Task<T> GetResultAsync<T>(int methodId, object? parameter = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -46,6 +47,7 @@ namespace mROA.Implementation
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, request.Id);
|
||||
localTokenSource.Cancel();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
@@ -76,21 +78,42 @@ namespace mROA.Implementation
|
||||
_representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id,
|
||||
MessageType.ExceptionCommandExecution, localTokenSource.Token);
|
||||
|
||||
cancellationToken.Register(async () =>
|
||||
{
|
||||
Console.WriteLine("Cancelling task");
|
||||
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest,
|
||||
new CancelRequest
|
||||
{
|
||||
Id = request.Id
|
||||
});
|
||||
localTokenSource.Cancel();
|
||||
});
|
||||
|
||||
Task.WaitAny(new Task[]
|
||||
{
|
||||
successResponse, errorResponse
|
||||
errorResponse, successResponse
|
||||
}, cancellationToken);
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, request.Id);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
Console.WriteLine($"Handling message");
|
||||
|
||||
// if (cancellationToken.IsCancellationRequested)
|
||||
// {
|
||||
// localTokenSource.Cancel();
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (successResponse.IsCompletedSuccessfully)
|
||||
return;
|
||||
|
||||
throw errorResponse.Result.GetException();
|
||||
if (errorResponse.IsCompletedSuccessfully)
|
||||
throw errorResponse.Result.GetException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_id == -1)
|
||||
return;
|
||||
CallAsync(-1).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,8 @@ namespace mROA.Implementation
|
||||
{
|
||||
var message = await _interaction.GetNextMessageReceiving();
|
||||
if ((requestId is not null && message.Id != requestId) ||
|
||||
(messageType is not null && message.SchemaId != messageType)) continue;
|
||||
(messageType is not null && message.SchemaId != messageType))
|
||||
continue;
|
||||
|
||||
_interaction.HandleMessage(message);
|
||||
return message.Data;
|
||||
@@ -79,7 +80,9 @@ namespace mROA.Implementation
|
||||
throw new NullReferenceException("Interaction toolkit is not initialized");
|
||||
if (_serialization == null)
|
||||
throw new NullReferenceException("Serialization toolkit is not initialized");
|
||||
|
||||
|
||||
Console.WriteLine($"Posting message: {id} - {messageType}");
|
||||
|
||||
await _interaction.PostMessage(new NetworkMessage
|
||||
{ Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType) });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user