Dear community,
I'm using the .net connector with RTI DDS 6.1.0.3 under Linux/WSL with .net 6 (the issue is the same in .net 5). My goal is to read the data published from dynamic_data_using_publisher_subscriber example and exit gracefully. The issue I'm facing, is that during Dispose I get an exception: PRESPsService_destroyLocalEndpoint:!delete local reader
My code is the following:
using Rti.Dds.Domain; using Rti.Dds.Subscription; using Rti.Dds.Topics; using Rti.Types.Dynamic; DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(0); DynamicType BuildShapeType() { var factory = DynamicTypeFactory.Instance; return factory.BuildStruct() .WithName("ShapeType") .AddMember(new StructMember("color", factory.CreateString(128), isKey: true)) .AddMember(new StructMember("x", factory.GetPrimitiveType<int>())) .AddMember(new StructMember("y", factory.GetPrimitiveType<int>())) .AddMember(new StructMember("shapesize", factory.GetPrimitiveType<int>())) .Create(); } Topic<DynamicData> topic = participant.CreateTopic("Square", BuildShapeType()); Subscriber subscriber = participant.CreateSubscriber(); DataReader<DynamicData> reader = subscriber.CreateDataReader(topic); reader.DataAvailable += OnDataAvailable; void OnDataAvailable(AnyDataReader _) { foreach (var sample in reader.Take()) if (sample.Info.ValidData) Console.WriteLine(sample.Data); else Console.WriteLine($"Instance state changed to: {sample.Info.State.Instance}"); } ManualResetEvent blocker = new(false); Console.CancelKeyPress += OnCancelKeyPress; void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e) { e.Cancel = true; blocker.Set(); } blocker.WaitOne(); reader.DataAvailable -= OnDataAvailable; Console.CancelKeyPress -= OnCancelKeyPress; participant.Dispose();
I start this application, then the dynamic_data_using_publisher_subscriber example. The samples are received and displayed. I stop the publisher, then I press ctrl+c to trigger the ManualResetEvent and finish my application. Exception is displayed.
This is the output:
color: "BLUE"
x: 50
y: 100
shapesize: 30
[...]
color: "BLUE"
x: 80
y: 100
shapesize: 45
Instance state changed to: NotAliveNoWriters
^C[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] PRESPsService_destroyLocalEndpoint:!delete local reader
[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] DDS_DataReader_deleteI:!delete PRESLocalEndpoint
[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] DDS_Subscriber_delete_datareader:!delete reader
Unhandled exception. Omg.Dds.Core.PreconditionNotMetException: DDS error stack:
[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] PRESPsService_destroyLocalEndpoint:!delete local reader
[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] DDS_DataReader_deleteI:!delete PRESLocalEndpoint
[0x0101E606,0xAAF52FA4,0x0213F34E:0x80000009{E=Su,D=0}|DELETE DR WITH TOPIC Square] DDS_Subscriber_delete_datareader:!delete reader
at Rti.Dds.NativeInterface.Helpers.ReturnCode.CheckResult(DDS_ReturnCode_t retcode)
at Rti.Dds.NativeInterface.Core.NativeStorageMethods.DestroyManagedObject(INativeStorage self, IntPtr nativeEntity, Func`2 deleteAction, Boolean throwOnError)
at Rti.Dds.NativeInterface.Core.NativeEntity.DestroyEntity(IntPtr nativeEntity, Func`2 deleteAction)
at Rti.Dds.NativeInterface.Subscription.NativeDataReader.DeleteNative(IntPtr reader)
at Rti.Dds.NativeInterface.Subscription.NativeDataReader.Dispose(Boolean freeManagedResources)
at Rti.Dds.NativeInterface.Core.NativeEntity.Dispose()
at Rti.Dds.Core.Entity.Dispose(Boolean disposing)
at Rti.Dds.Subscription.AnyDataReader.Dispose(Boolean closing)
at Rti.Dds.Subscription.Subscriber.DisposeContainedEntities()
at Rti.Dds.Subscription.Subscriber.Dispose(Boolean closing)
at Rti.Dds.Domain.DomainParticipant.DisposeContainedEntities()
at Rti.Dds.Domain.DomainParticipant.Dispose(Boolean disposing)
at Rti.Dds.Core.Entity.Dispose()
at Program.<Main>$(String[] args) in /home/z001x91h/repos/local/datareadertest/Program.cs:line 51
My question is: What am I doing wrong?
Thank you,
Andras
The issue seems to be here:
foreach
(var sample
in
reader.Take())
The collection of LoanedSamples returned by Read/Take must be returned to the middleware by disposing it (for ex. with the "using" keyword):
using var samples = reader.Take()
foreach (var sample in samples)
See https://community.rti.com/static/documentation/connext-dds/current/doc/api/connext_dds/api_csharp/class_rti_1_1_dds_1_1_subscription_1_1_loaned_samples.html
Thank you! It is working now!