async Task <IEnumerable <DiscoveryDevice> > Discover(int timeout, IOnvifUdpClient client, CancellationToken cancellationToken = default) { Guid messageId = Guid.NewGuid(); var responses = new List <UdpReceiveResult> (); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout)); try { await SendProbe(client, messageId); while (true) { if (cts.IsCancellationRequested || cancellationToken.IsCancellationRequested) { break; } var response = await client.ReceiveAsync().WithCancellation(cancellationToken).WithCancellation(cts.Token); if (!IsAlreadyDiscovered(response, responses)) { responses.Add(response); } } } catch (OperationCanceledException) { // Either the user canceled the action or the timeout has fired } finally { client.Close(); } if (cancellationToken.IsCancellationRequested) { return(new List <DiscoveryDevice> ()); } return(ProcessResponses(responses, messageId)); }
async Task Discover(int timeout, IOnvifUdpClient client, Action <DiscoveryDevice> onDeviceDiscovered, CancellationToken cancellationToken = default) { Guid messageId = Guid.NewGuid(); var responses = new List <UdpReceiveResult> (); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeout)); try { await SendProbe(client, messageId); while (true) { if (cts.IsCancellationRequested || cancellationToken.IsCancellationRequested) { break; } try { var response = await client.ReceiveAsync() .WithCancellation(cancellationToken) .WithCancellation(cts.Token); if (IsAlreadyDiscovered(response, responses)) { continue; } responses.Add(response); var discoveredDevice = ProcessResponse(response, messageId); if (discoveredDevice != null) { #pragma warning disable 4014 // Just trigger the callback and forget about it. This is expected to avoid locking the loop Task.Run(() => onDeviceDiscovered(discoveredDevice)); #pragma warning restore 4014 } } catch (OperationCanceledException) { // Either the user canceled the action or the timeout has fired } catch (Exception) { // we catch all exceptions ! // Something might be bad in the response of a camera when call ReceiveAsync (BeginReceive in socket) fail } } } finally { client.Close(); } }