/// <summary> /// WaitBenchmarkResult returns <see cref="BenchmarkResult"/> after one of 3 conditions is fullfiled. /// Conditions are: Benchmark fails with error message, Benchmarks timeouts, Benchmark returns non-zero speed /// </summary> /// <param name="benchmarkProcess">Is the running <see cref="BenchmarkProcess"/></param> /// <param name="timeoutTime">Is the time after which we get timeout</param> /// <param name="delayTime">Is the delay time after which <paramref name="timeoutTime"/> starts counting</param> /// <param name="stop">Is the <see cref="CancellationToken"/> for stopping <paramref name="benchmarkProcess"/></param> public static async Task <BenchmarkResult> WaitBenchmarkResult(BenchmarkProcess benchmarkProcess, TimeSpan timeoutTime, TimeSpan delayTime, CancellationToken stop) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; var timeoutTimerTime = timeoutTime + delayTime; using (var timeoutSource = new CancellationTokenSource(timeoutTimerTime)) { BenchmarkResult ret = null; var timeout = timeoutSource.Token; using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeout, stop)) { try { await Task.Delay(delayTime, linkedCts.Token); ret = await benchmarkProcess.Execute(linkedCts.Token); } catch (OperationCanceledException) { } catch (Exception e) { Logger.Info("MinerToolkit", $"Error occured while waiting for benchmark result: {e.Message}"); return(new BenchmarkResult { ErrorMessage = e.Message }); } } // #1 if canceled return canceled if (stop.IsCancellationRequested) { Logger.Info("MinerToolkit", "Benchmark process was canceled by user"); return(new BenchmarkResult { ErrorMessage = "Cancelling per user request." }); } if (ret == null) { return new BenchmarkResult { ErrorMessage = "Benchmark result is null" } } ; if (ret.HasNonZeroSpeeds() || !string.IsNullOrEmpty(ret.ErrorMessage)) { return(ret); } if (timeout.IsCancellationRequested) { Logger.Info("MinerToolkit", "Benchmark process timed out"); return(new BenchmarkResult { ErrorMessage = "Operation timed out." }); } } return(new BenchmarkResult()); }