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); } } }
private async Task ScanAsync() { var isEntered = false; try { isEntered = (Interlocked.Increment(ref _scanCount) == 1); if (isEntered) { ScanningChanged?.Invoke(this, true); var scanTime = DateTimeOffset.Now; int accessibleMonitorCount = 0; await Task.Run(() => { var oldMonitorIndices = Enumerable.Range(0, Monitors.Count).ToList(); var newMonitorItems = new List <IMonitor>(); foreach (var item in MonitorManager.EnumerateMonitors()) { var isExisting = false; foreach (int index in oldMonitorIndices) { var oldMonitor = Monitors[index]; if (string.Equals(oldMonitor.DeviceInstanceId, item.DeviceInstanceId, StringComparison.OrdinalIgnoreCase) && (oldMonitor.IsAccessible == item.IsAccessible)) { isExisting = true; oldMonitorIndices.Remove(index); item.Dispose(); break; } } if (!isExisting) { 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); if (newMonitor.IsControllable && (Monitors.Count < _maxMonitorCount.Value)) { newMonitor.UpdateBrightness(); newMonitor.IsTarget = true; accessibleMonitorCount++; } lock (_monitorsLock) { Monitors.Add(newMonitor); } } } }); await Task.WhenAll(Monitors .Take(_maxMonitorCount.Value) .Where(x => x.IsControllable && (x.UpdateTime < scanTime)) .Select(x => Task.Run(() => { x.UpdateBrightness(); x.IsTarget = true; Interlocked.Increment(ref accessibleMonitorCount); }))); var accessibleMonitorExists = (accessibleMonitorCount > 0); Monitors .Where(x => !x.IsControllable) .ToList() .ForEach(x => x.IsTarget = !accessibleMonitorExists); } } finally { if (isEntered) { ScanningChanged?.Invoke(this, false); Interlocked.Exchange(ref _scanCount, 0); } } }