From 6b898653c1e69db30589c5419c014d4bd4cf0b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Thu, 17 Aug 2023 18:37:07 +0200 Subject: [PATCH] Add support for resolving a service asynchronously (task-based) Also, BeginInvoke [throws PlatformNotSupportedException on .NET Core][1] [1]: https://stackoverflow.com/questions/45183294/begininvoke-not-supported-on-net-core-platformnotsupported-exception --- Arkane.Zeroconf/IResolvableService.cs | 4 ++++ .../Providers/Bonjour/BrowseService.cs | 20 +++++++++++++++---- .../Providers/Bonjour/ServiceRef.cs | 13 ++++++++++-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Arkane.Zeroconf/IResolvableService.cs b/Arkane.Zeroconf/IResolvableService.cs index 490be3d..1ac5442 100644 --- a/Arkane.Zeroconf/IResolvableService.cs +++ b/Arkane.Zeroconf/IResolvableService.cs @@ -8,6 +8,8 @@ #region using using System.Net ; +using System.Threading ; +using System.Threading.Tasks ; #endregion @@ -30,4 +32,6 @@ public interface IResolvableService : IService event ServiceResolvedEventHandler Resolved ; void Resolve () ; + + Task ResolveAsync (CancellationToken cancellationToken = default) ; } diff --git a/Arkane.Zeroconf/Providers/Bonjour/BrowseService.cs b/Arkane.Zeroconf/Providers/Bonjour/BrowseService.cs index d28e9f2..087b331 100644 --- a/Arkane.Zeroconf/Providers/Bonjour/BrowseService.cs +++ b/Arkane.Zeroconf/Providers/Bonjour/BrowseService.cs @@ -12,6 +12,8 @@ using System.Net ; using System.Runtime.InteropServices ; using System.Text ; +using System.Threading ; +using System.Threading.Tasks ; #endregion @@ -28,8 +30,8 @@ public BrowseService (string name, string replyDomain, string regtype) : base (n private Native.DNSServiceQueryRecordReply queryRecordReplyHandler ; - private Action resolveAction ; - private bool resolvePending ; + private Action resolveAction ; + private bool resolvePending ; private Native.DNSServiceResolveReply resolveReplyHandler ; @@ -43,7 +45,12 @@ public void Resolve () { // If people call this in a ServiceAdded event handler (which they generally do), we need to // invoke onto another thread, otherwise we block processing any more results. - this.resolveResult = this.resolveAction.BeginInvoke (false, null, null) ; + this.resolveResult = ResolveAsync () ; + } + + public Task ResolveAsync (CancellationToken cancellationToken = default) + { + return Task.Run (() => this.resolveAction (false, cancellationToken), cancellationToken) ; } ~BrowseService () @@ -60,6 +67,11 @@ private void SetupCallbacks () } public void Resolve (bool requery) + { + Resolve (requery, CancellationToken.None) ; + } + + public void Resolve (bool requery, CancellationToken cancellationToken) { if (this.resolvePending) return ; @@ -82,7 +94,7 @@ public void Resolve (bool requery) if (error != ServiceError.NoError) throw new ServiceErrorException (error) ; - sdRef.Process () ; + sdRef.Process (cancellationToken) ; } public void RefreshTxtRecord () diff --git a/Arkane.Zeroconf/Providers/Bonjour/ServiceRef.cs b/Arkane.Zeroconf/Providers/Bonjour/ServiceRef.cs index 528d3ae..111e9e4 100644 --- a/Arkane.Zeroconf/Providers/Bonjour/ServiceRef.cs +++ b/Arkane.Zeroconf/Providers/Bonjour/ServiceRef.cs @@ -8,6 +8,7 @@ #region using using System ; +using System.Threading ; #endregion @@ -25,8 +26,16 @@ public struct ServiceRef public void Process () { - while (this.ProcessSingle () == ServiceError.NoError) - { } + Process(CancellationToken.None); + } + + public void Process (CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + while (this.ProcessSingle() == ServiceError.NoError) + { + cancellationToken.ThrowIfCancellationRequested(); + } } public int SocketFD => Native.DNSServiceRefSockFD (this.Raw) ;