示例#1
0
        public async Task <T> CancelAfterTimeoutAsync <T>(Func <CancellationToken, Task <T> > taskProvider, TimeSpan timeout, bool throwOnTimeout,
                                                          CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(await taskProvider.Invoke(cancellationToken).ConfigureAwait(false));
            }

            using (var timeoutCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                using (var linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                {
                    var stopwatch = new Stopwatch();
                    stopwatch.Start();

                    var task = Task.Run(() => taskProvider.Invoke(linkedCancellation.Token));
                    var firstCompletedTask = await Task.WhenAny(task, CancellableDelay(timeout, timeoutCancellation.Token)).ConfigureAwait(false);

                    stopwatch.Stop();

                    if (cancellationToken.IsCancellationRequested)
                    {
                        _bleLogger?.Log(LogSender, $"Task was cancelled after {stopwatch.Elapsed} (timeout = {timeout})");
                        return(await task);
                    }

                    if (ReferenceEquals(firstCompletedTask, task))
                    {
                        _bleLogger?.Log(LogSender, $"Task was completed after {stopwatch.Elapsed} (timeout = {timeout})");
                        timeoutCancellation.Cancel();
                        return(await task);
                    }

                    _bleLogger?.Log(LogSender, $"Task was timed out after {stopwatch.Elapsed} (timeout = {timeout})");
                    linkedCancellation.Cancel();
                    if (!throwOnTimeout)
                    {
                        return(await task);
                    }

                    HandleTaskExceptions(task);
                    throw new TimeoutException($"Operation timed out after {timeout}");
                }
            }
        }
示例#2
0
        public Task <IBleResult> TryConnectToDeviceAsync(IDevice device, bool connectWhenAvailable, CancellationToken cancellationToken)
        {
            _logger?.Log(LogSender, $"Trying to connect to device [DeviceName={device.Name},GUID={device.Id:D}]");

            return(_bleAvailability.ExecuteWithBleAvailabilityCheckAsync(async() =>
            {
                IBleResult result;

                _logger?.Log(LogSender, $"Internal connect to device started");
                try
                {
                    var connectParameters = new ConnectParameters(connectWhenAvailable);
                    await _bleAdapter.ConnectToDeviceAsync(device, connectParameters, cancellationToken);
                    result = device.State == DeviceState.Connected ? BleResult.Success() : BleResult.Failure(BleFailure.ConnectNotCompleted);
                }
                catch (TimeoutException)
                {
                    result = BleResult.Failure(BleFailure.OperationTimeout);
                }
                catch (OperationCanceledException)
                {
                    result = BleResult.Failure(BleFailure.OperationCancelled);
                }
                catch (Exception e)
                {
                    result = BleResult.Failure(e);
                }
                _logger?.Log(LogSender, $"Internal connect to device completed with result: {result}");

                return result;
            }));
        }
示例#3
0
 public void HandleTaskExceptions(Task task)
 {
     task.ContinueWith(t =>
     {
         t.Exception.Handle(ex =>
         {
             _bleLogger.Log(LogSender, $"Unhandled exception {ex.Message}, stacktrace=[{ex.StackTrace}]");
             return(true);
         });
     }, TaskContinuationOptions.OnlyOnFaulted);
 }
示例#4
0
 private void OnDeviceDiscovered(object sender, DeviceEventArgs e)
 {
     try
     {
         _logger?.Log(LogSender, $"Device discovered, DeviceName={e.Device?.Name ?? "N/A"}");
         if (_deviceFilter.IsWantedDevice(e.Device))
         {
             _logger?.Log(LogSender, $"Wanted device found, DeviceName={e.Device?.Name ?? "N/A"}");
             _observer.OnNext(e.Device);
             if (_stopAfterFirstResult)
             {
                 _logger?.Log(LogSender, "Completing search");
                 _searchCancellation.Cancel();
             }
         }
     }
     catch (Exception ex)
     {
         _logger?.Log(LogSender, $"Exception while discovering device: {ex}");
     }
 }
示例#5
0
        void IListener <ConnectionEvent> .Notify(ConnectionEvent value)
        {
            switch (value)
            {
            case ConnectionEvent.ConnectionLost:
                _executor.RunWithoutAwaiting(RestartConnectionAsync);
                break;

            case ConnectionEvent.Disconnected:
                _logger.Log(LogSender, "WARNING! Device was disconnected while in KeepConnection mode");
                break;
            }
        }
示例#6
0
        public SearchAdapter(IAdapter bleAdapter, IObserver <IDevice> observer, IDeviceFilter deviceFilter, bool stopAfterFirstResult,
                             IExecutor executor, IBleLogger logger, CancellationToken cancellationToken)
        {
            _bleAdapter           = bleAdapter;
            _observer             = observer;
            _deviceFilter         = deviceFilter;
            _stopAfterFirstResult = stopAfterFirstResult;
            _executor             = executor;
            _logger = logger;

            _searchCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            _searchCancellation.Token.Register(OnSearchInterrupted, false);

            _logger?.Log(LogSender, $"Starting search {DateTime.Now} (stopAfterFirstResult={stopAfterFirstResult})");
            _executor.RunWithoutAwaiting(() => TryStartSearchAsync(_searchCancellation.Token));
        }