private void SetAllCompleted(int index, TaskRetryResult result) { for (var i = index; i < _maxTimes; i++) { _waiters[i].TrySetResult(result); } }
private void ExecuteImpl(Func <ServiceInfo, Task> action, int index = 0) { if (index >= 0 && index < _maxTimes) { var service = _selector.GetOne(); if (service != null) { var sw = new Stopwatch(); sw.Restart(); action(service).ContinueWith(t => { TaskRetryResult result = null; if (t.Exception != null) { //_waiters[index].TrySetException(t.Exception); var ex = t.Exception.GetInnerException();//.GetBaseException(); result = new TaskRetryResult(service, ex); var exType = ex.GetType(); if (_exceptionTypes.Count == 0 || _exceptionTypes.Contains(ex.GetType()) || _exceptionTypes.Any(e => e.IsAssignableFrom(exType))) { _waiters[index].SetResult(result); _logger.LogInformation($"执行失败,开始第{index + 1}次重试{service.Name}:{ex.Message}"); ExecuteImpl(action, index + 1);//todo:间隔一段时间重试。。。可配置 return; } //不需要重试,后面统一设置完成状态 } else { object value = null; if (t.GetType().IsGenericType) //is Task<T> { value = t.GetType().GetProperty("Result").GetValue(t); //dynamic? } result = new TaskRetryResult(service, value) { Duration = sw.Elapsed }; } //将剩余的设置为完成 SetAllCompleted(index, result); }); } else { _waiters[index].SetResult(new TaskRetryResult(new Exception("no available service")));//todo:throw cob custom exception ExecuteImpl(action, index + 1); } } }