public void TestTaskHelper() { TaskHelper.GetUnderlyingType(typeof(Task <int>), out bool isTask).ShouldBe(typeof(int)); isTask.ShouldBe(true); TaskHelper.GetUnderlyingType(typeof(Task), out isTask).ShouldBe(null); isTask.ShouldBe(true); TaskHelper.GetUnderlyingType(typeof(int), out isTask).ShouldBe(typeof(int)); isTask.ShouldBe(false); TaskHelper.ConvertToGeneric(typeof(int), Task.FromResult <object>(1)).ShouldBeAssignableTo(typeof(Task <int>)); TaskHelper.GetResult(Task.FromResult(1)).ShouldBe(1); TaskHelper.GetResult(Task.CompletedTask).ShouldBe(null); }
private object ExecuteAsync(Type returnType, CobServiceDescription desc, Func <ServiceInfo, Task> action, MethodInfo method = null, Dictionary <string, object> parameters = null) { var retry = new ServiceTaskRetryContainer(_loggerFactory, _selector, desc.RetryTimes, desc.RetryExceptionTypes); var taskResult = retry.RunForResult(action).ContinueWith(t => { foreach (var item in t.Result) { if (item.Service != null) { //set exception,超过阈值后熔断 if (item.Exception != null) { _selector.MarkServiceFailed(item.Service, false); } else if (item.Duration.HasValue) { _selector.MarkServiceHealthy(item.Service, item.Duration.Value); } } } if (t.Result.All(i => i.Exception != null)) { var ex = t.Result.First().Exception.GetInnerException(); //failover //降级 fallback if (desc.FallbackHandler != null) { _logger.LogInformation("使用缺省值处理类返回"); var handler = _fallbackHandlers.GetOrAdd(desc.FallbackHandler, k => Activator.CreateInstance(k) as ICobFallbackHandler); return(handler?.GetValue(new CobFallbackHandlerContext { ReturnType = returnType, Exception = ex, ServiceName = desc.ServiceName, Path = desc.Path, Method = method, Parameters = parameters })); } else if (!string.IsNullOrWhiteSpace(desc.FallbackValue)) { _logger.LogInformation("使用缺省值返回"); return(_scripts.GetOrAdd(desc.FallbackValue, k => CSharpScript.EvaluateAsync(k).ConfigureAwait(false).GetAwaiter().GetResult()));//todo:处理是否为Task } //没有缺省值时,抛出异常 throw ex; } return(t.Result.FirstOrDefault(i => i.Exception == null)?.Result); }); var realType = TaskHelper.GetUnderlyingType(returnType, out bool isTask); //匹配返回的类型 if (isTask) { return(TaskHelper.ConvertToGeneric(realType, taskResult)); } else if (realType != null) { return(taskResult.ConfigureAwait(false).GetAwaiter().GetResult());//todo:在beforeRequest时抛出异常,这里就会一直等待? } return(null);//todo:change to default(T) ?? }