init
This commit is contained in:
126
DataPRO/DASFactory/DASFactory.AutoDiscovery.cs
Normal file
126
DataPRO/DASFactory/DASFactory.AutoDiscovery.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.DASFactory
|
||||
{
|
||||
internal class AutoDiscovery
|
||||
{
|
||||
private readonly IDASFactory _dasFactory;
|
||||
/// <summary>
|
||||
/// this is the task that is actively looking for UDP devices
|
||||
/// </summary>
|
||||
private Task _scanTask = null;
|
||||
/// <summary>
|
||||
/// this is the cancellation token source for the cancel token used by the scan task
|
||||
/// </summary>
|
||||
private CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||
/// <summary>
|
||||
/// this is a lock used to make start/stop and Get thread safe
|
||||
/// </summary>
|
||||
private static readonly object _multicastLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// starts a background discovery process
|
||||
/// </summary>
|
||||
public void StartMulticastAutoDiscovery()
|
||||
{
|
||||
lock (_multicastLock)
|
||||
{
|
||||
//start scanning (unless we are already scanning)
|
||||
if (null == _scanTask || _scanTask.IsCompleted)
|
||||
{
|
||||
if (tokenSource.IsCancellationRequested)
|
||||
{
|
||||
tokenSource.Dispose();
|
||||
// token has been cancelled. no "reset" other than creating a new token source
|
||||
tokenSource = new CancellationTokenSource();
|
||||
}
|
||||
_scanTask = Task.Run(() => DiscoveryWork(null, tokenSource.Token, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// stops a background discovery process
|
||||
/// </summary>
|
||||
public void StopMulticastAutoDiscovery()
|
||||
{
|
||||
lock (_multicastLock)
|
||||
{
|
||||
//stop scanning (unless it's not currently scanning)
|
||||
if (null == _scanTask || _scanTask.IsCompleted) { return; }
|
||||
if (tokenSource.Token.CanBeCanceled)
|
||||
{
|
||||
tokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
_scanTask.Wait();
|
||||
_scanTask = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// list of any discovered devices since discovery started
|
||||
/// </summary>
|
||||
private readonly List<IDiscoveredDevice> _discoveredDevices = new List<IDiscoveredDevice>();
|
||||
/// <summary>
|
||||
/// this is the actual discovery thread
|
||||
/// </summary>
|
||||
/// <param name="deviceFilter"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <param name="discoverParents"></param>
|
||||
private void DiscoveryWork(DFConstantsAndEnums.MultiCastDeviceClasses[] deviceFilter, CancellationToken ct, bool discoverParents = true)
|
||||
{
|
||||
var keepGoing = !ct.IsCancellationRequested;
|
||||
|
||||
ClearDiscoveredDevices();
|
||||
while (keepGoing)
|
||||
{
|
||||
var discoveries = _dasFactory.AutoDiscoverMulticast(ct, discoverParents).ToArray();
|
||||
var filteredDiscoveries = deviceFilter?.Count() > 0 ? discoveries.Where(x => deviceFilter.Contains(x.DevClass)).ToArray() : discoveries;
|
||||
UpdateDevices(filteredDiscoveries);
|
||||
ct.WaitHandle.WaitOne(1000);
|
||||
keepGoing = !ct.IsCancellationRequested;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds any new devices to list of devices
|
||||
/// does not change any existing entries
|
||||
/// </summary>
|
||||
/// <param name="devices"></param>
|
||||
private void UpdateDevices(IDiscoveredDevice[] devices)
|
||||
{
|
||||
lock (_multicastLock)
|
||||
{
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (!_discoveredDevices.Exists(x => x.Serial == device.Serial))
|
||||
{
|
||||
_discoveredDevices.Add(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// clears any discovered devices
|
||||
/// </summary>
|
||||
private void ClearDiscoveredDevices()
|
||||
{
|
||||
lock (_multicastLock) { _discoveredDevices.Clear(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// retrieves all discovered devices
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDiscoveredDevice[] GetDiscoveredDevices()
|
||||
{
|
||||
lock (_multicastLock) { return _discoveredDevices.ToArray(); }
|
||||
}
|
||||
|
||||
public AutoDiscovery(IDASFactory dasFactory)
|
||||
{
|
||||
_dasFactory = dasFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user