private async Task ScanAsync() { var isEntered = false; try { isEntered = (Interlocked.Increment(ref _scanCount) == 1); if (isEntered) { ScanningChanged?.Invoke(this, true); await Task.Run(async() => { var oldMonitorIndices = Enumerable.Range(0, Monitors.Count).ToList(); var newMonitorItems = new List <IMonitor>(); foreach (var item in await MonitorManager.EnumerateMonitorsAsync()) { var oldMonitorExists = false; foreach (int index in oldMonitorIndices) { var oldMonitor = Monitors[index]; if (string.Equals(oldMonitor.DeviceInstanceId, item.DeviceInstanceId, StringComparison.OrdinalIgnoreCase) && (oldMonitor.IsAccessible == item.IsAccessible)) { oldMonitorExists = true; oldMonitorIndices.Remove(index); item.Dispose(); break; } } if (!oldMonitorExists) { newMonitorItems.Add(item); } } if (oldMonitorIndices.Count > 0) { oldMonitorIndices.Reverse(); // Reverse indices to start removing from the tail. foreach (var index in oldMonitorIndices) { Monitors[index].Dispose(); lock (_monitorsLock) { Monitors.RemoveAt(index); } } } if (newMonitorItems.Count > 0) { foreach (var item in newMonitorItems) { var newMonitor = new MonitorViewModel(this, item); lock (_monitorsLock) { Monitors.Add(newMonitor); } } } }); var controllableMonitorExists = false; await Task.WhenAll(Monitors .Where(x => x.IsControllable) .Select((x, index) => { controllableMonitorExists = true; if (index < _maxMonitorCount.Value) { return(Task.Run(() => { x.UpdateBrightness(); x.IsTarget = true; })); } else { x.IsTarget = false; return(Task.CompletedTask); } })); Monitors .Where(x => !x.IsControllable) .ToList() .ForEach(x => x.IsTarget = !controllableMonitorExists); } } finally { if (isEntered) { ScanningChanged?.Invoke(this, false); Interlocked.Exchange(ref _scanCount, 0); } } }
private async Task ScanAsync(TimeSpan interval) { var isEntered = false; try { isEntered = (Interlocked.Increment(ref _scanCount) == 1); if (isEntered) { ScanningChanged?.Invoke(this, true); var intervalTask = (interval > TimeSpan.Zero) ? Task.Delay(interval) : Task.CompletedTask; _recorder?.StartRecord($"{nameof(ScanAsync)} [{DateTime.Now}]"); await Task.Run(async() => { var oldMonitorIndices = Enumerable.Range(0, Monitors.Count).ToList(); var newMonitorItems = new List <IMonitor>(); foreach (var item in await MonitorManager.EnumerateMonitorsAsync()) { _recorder?.AddItem("Items", item.ToString()); var oldMonitorExists = false; foreach (int index in oldMonitorIndices) { var oldMonitor = Monitors[index]; if (string.Equals(oldMonitor.DeviceInstanceId, item.DeviceInstanceId, StringComparison.OrdinalIgnoreCase) && (oldMonitor.IsReachable == item.IsReachable)) { oldMonitorExists = true; oldMonitorIndices.Remove(index); oldMonitor.Replace(item); break; } } if (!oldMonitorExists) { newMonitorItems.Add(item); } } if (oldMonitorIndices.Count > 0) { oldMonitorIndices.Reverse(); // Reverse indices to start removing from the tail. foreach (int index in oldMonitorIndices) { DisposeMonitor(Monitors[index]); lock (_monitorsLock) { Monitors.RemoveAt(index); } } } if (newMonitorItems.Count > 0) { foreach (var item in newMonitorItems) { var newMonitor = GetMonitor(item); lock (_monitorsLock) { Monitors.Add(newMonitor); } } } }); var maxMonitorsCount = await GetMaxMonitorsCountAsync(); var updateResults = await Task.WhenAll(Monitors .Where(x => x.IsLikelyControllable) .Select((x, index) => { if (index < maxMonitorsCount) { return(Task.Run(() => { if (x.UpdateBrightness()) { x.IsTarget = true; } return x.IsControllable; })); } x.IsTarget = false; return(Task.FromResult(false)); })); var controllableMonitorExists = updateResults.Any(x => x); foreach (var m in Monitors.Where(x => !x.IsControllable)) { m.IsTarget = !controllableMonitorExists; } _recorder?.AddItems(nameof(Monitors), Monitors.Select(x => x.ToString())); _recorder?.StopRecord(); await intervalTask; } } finally { if (isEntered) { ScanningChanged?.Invoke(this, false); Interlocked.Exchange(ref _scanCount, 0); } } }
private async Task ScanAsync() { var isEntered = false; try { isEntered = (Interlocked.Increment(ref _scanCount) == 1); if (isEntered) { ScanningChanged?.Invoke(this, true); var scanTime = DateTimeOffset.Now; await Task.Run(() => { var oldMonitors = Monitors.ToList(); foreach (var item in MonitorManager.EnumerateMonitors()) { var oldMonitor = oldMonitors.FirstOrDefault(x => string.Equals(x.DeviceInstanceId, item.DeviceInstanceId, StringComparison.OrdinalIgnoreCase)); if (oldMonitor != null) { oldMonitors.Remove(oldMonitor); item.Dispose(); continue; } var newMonitor = new MonitorViewModel(item); RetrieveName(newMonitor); if (Monitors.Count < _maxMonitorCount.Value) { newMonitor.UpdateBrightness(); newMonitor.IsTarget = true; } lock (_monitorsLock) { Monitors.Add(newMonitor); } } foreach (var oldMonitor in oldMonitors) { oldMonitor.Dispose(); lock (_monitorsLock) { Monitors.Remove(oldMonitor); } } }); await Task.WhenAll(Monitors .Take(_maxMonitorCount.Value) .Where(x => x.UpdateTime < scanTime) .Select(x => Task.Run(() => { x.UpdateBrightness(); x.IsTarget = true; }))); } } finally { if (isEntered) { ScanningChanged?.Invoke(this, false); Interlocked.Exchange(ref _scanCount, 0); } } }