diff --git a/rcldotnet_examples/CMakeLists.txt b/rcldotnet_examples/CMakeLists.txt index 64d64f89..a5518444 100644 --- a/rcldotnet_examples/CMakeLists.txt +++ b/rcldotnet_examples/CMakeLists.txt @@ -45,9 +45,16 @@ add_dotnet_executable(rcldotnet_example_client ${_assemblies_dep_dlls} ) +add_dotnet_executable(rcldotnet_guard_condition + RCLDotnetGuardCondition.cs + INCLUDE_DLLS + ${_assemblies_dep_dlls} +) + install_dotnet(rcldotnet_talker DESTINATION lib/${PROJECT_NAME}/dotnet) install_dotnet(rcldotnet_listener DESTINATION lib/${PROJECT_NAME}/dotnet) install_dotnet(rcldotnet_example_service DESTINATION lib/${PROJECT_NAME}/dotnet) install_dotnet(rcldotnet_example_client DESTINATION lib/${PROJECT_NAME}/dotnet) +install_dotnet(rcldotnet_guard_condition DESTINATION lib/${PROJECT_NAME}/dotnet) ament_package() diff --git a/rcldotnet_examples/RCLDotnetGuardCondition.cs b/rcldotnet_examples/RCLDotnetGuardCondition.cs new file mode 100644 index 00000000..04d2cc1a --- /dev/null +++ b/rcldotnet_examples/RCLDotnetGuardCondition.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +using ROS2; + +namespace ConsoleApplication +{ + public static class RCLDotnetGuardCondition + { + static GuardCondition _guardCondition = null; + + public static void Main(string[] args) + { + RCLdotnet.Init(); + + var node = RCLdotnet.CreateNode("guard_condition_example"); + + _guardCondition = node.CreateGuardCondition(GuardConditionTriggered); + + Console.WriteLine($"RMWIdentifier: {RCLdotnet.GetRMWIdentifier()}"); + + _guardCondition.Trigger(); + Console.WriteLine($"{DateTimeOffset.Now:O} ThreadId: {Environment.CurrentManagedThreadId} - Initial trigger of GuardCondition."); + + RCLdotnet.Spin(node); + } + + static void GuardConditionTriggered() + { + Console.WriteLine($"{DateTimeOffset.Now:O} ThreadId: {Environment.CurrentManagedThreadId} - GuardCondition was triggered."); + _ = TriggerAfterSomeTime(); + } + + static async Task TriggerAfterSomeTime() + { + // This is a multiple of the 500ms used in the loop in + // RCLdotnet.Spin(). So the guard condition will be triggered nearly + // at the same time as the wait times out. This is to test/reproduce + // if the combination of rcldotnet and the rmw implementation have + // an race-conditions in that case. + await Task.Delay(TimeSpan.FromSeconds(1)); + + // This will be called in an background worker thread as console + // applications don't have an SynchronizationContext by default. + _guardCondition.Trigger(); + Console.WriteLine($"{DateTimeOffset.Now:O} ThreadId: {Environment.CurrentManagedThreadId} - Triggered GuardCondition."); + } + } +}