Browse Source
- 修复单例服务注入作用域服务的问题 - 创建通用服务作用域执行器 (IServiceScopeExecutor) - 重构DeviceManagementService使用通用执行器 - 优化BackgroundService执行逻辑 - 减少轮询延迟从100ms到10ms - 移除多余的Task.Run调用 - 添加详细的操作结果包装类feature/x1-web-request
5 changed files with 491 additions and 102 deletions
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace X1.Application.BackendServiceManager |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 服务作用域执行器接口
|
||||
|
/// </summary>
|
||||
|
public interface IServiceScopeExecutor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 安全地执行作用域服务操作,返回操作结果包装
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">操作返回的数据类型</typeparam>
|
||||
|
/// <param name="operation">要执行的操作</param>
|
||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||
|
/// <returns>操作结果</returns>
|
||||
|
Task<ScopeOperationResult<T>> ExecuteWithResultAsync<T>(Func<IServiceProvider, Task<T>> operation, CancellationToken cancellationToken = default); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 安全地执行无返回值的作用域服务操作
|
||||
|
/// </summary>
|
||||
|
/// <param name="operation">要执行的操作</param>
|
||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||
|
/// <returns>操作结果</returns>
|
||||
|
Task<ScopeOperationResult> ExecuteAsync(Func<IServiceProvider, Task> operation, CancellationToken cancellationToken = default); |
||||
|
} |
||||
|
} |
@ -0,0 +1,109 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace X1.Application.BackendServiceManager |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 作用域服务操作结果包装类,用于表示作用域服务操作的成功或失败状态
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">操作返回的数据类型</typeparam>
|
||||
|
public class ScopeOperationResult<T> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 操作是否成功
|
||||
|
/// </summary>
|
||||
|
public bool IsSuccess { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 操作返回的数据
|
||||
|
/// </summary>
|
||||
|
public T Data { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 错误消息
|
||||
|
/// </summary>
|
||||
|
public string ErrorMessage { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 私有构造函数
|
||||
|
/// </summary>
|
||||
|
private ScopeOperationResult(bool isSuccess, T data, string errorMessage) |
||||
|
{ |
||||
|
IsSuccess = isSuccess; |
||||
|
Data = data; |
||||
|
ErrorMessage = errorMessage; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建成功结果
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">操作返回的数据</param>
|
||||
|
/// <returns>成功的结果</returns>
|
||||
|
public static ScopeOperationResult<T> Success(T data) |
||||
|
{ |
||||
|
return new ScopeOperationResult<T>(true, data, null); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建失败结果
|
||||
|
/// </summary>
|
||||
|
/// <param name="errorMessage">错误消息</param>
|
||||
|
/// <returns>失败的结果</returns>
|
||||
|
public static ScopeOperationResult<T> Failure(string errorMessage) |
||||
|
{ |
||||
|
return new ScopeOperationResult<T>(false, default(T), errorMessage); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 隐式转换操作符,从 T 转换为 ScopeOperationResult<T>
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">数据</param>
|
||||
|
public static implicit operator ScopeOperationResult<T>(T data) |
||||
|
{ |
||||
|
return Success(data); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 无返回值的作用域服务操作结果类
|
||||
|
/// </summary>
|
||||
|
public class ScopeOperationResult |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 操作是否成功
|
||||
|
/// </summary>
|
||||
|
public bool IsSuccess { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 错误消息
|
||||
|
/// </summary>
|
||||
|
public string ErrorMessage { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 私有构造函数
|
||||
|
/// </summary>
|
||||
|
private ScopeOperationResult(bool isSuccess, string errorMessage) |
||||
|
{ |
||||
|
IsSuccess = isSuccess; |
||||
|
ErrorMessage = errorMessage; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建成功结果
|
||||
|
/// </summary>
|
||||
|
/// <returns>成功的结果</returns>
|
||||
|
public static ScopeOperationResult Success() |
||||
|
{ |
||||
|
return new ScopeOperationResult(true, null); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建失败结果
|
||||
|
/// </summary>
|
||||
|
/// <param name="errorMessage">错误消息</param>
|
||||
|
/// <returns>失败的结果</returns>
|
||||
|
public static ScopeOperationResult Failure(string errorMessage) |
||||
|
{ |
||||
|
return new ScopeOperationResult(false, errorMessage); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,131 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
|
||||
|
namespace X1.Application.BackendServiceManager |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 服务作用域执行器实现类
|
||||
|
/// </summary>
|
||||
|
public class ServiceScopeExecutor : IServiceScopeExecutor |
||||
|
{ |
||||
|
private readonly IServiceScopeFactory _serviceScopeFactory; |
||||
|
private readonly ILogger<ServiceScopeExecutor> _logger; |
||||
|
|
||||
|
public ServiceScopeExecutor( |
||||
|
IServiceScopeFactory serviceScopeFactory, |
||||
|
ILogger<ServiceScopeExecutor> logger) |
||||
|
{ |
||||
|
_serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory)); |
||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 安全地执行作用域服务操作,返回操作结果包装
|
||||
|
/// </summary>
|
||||
|
public async Task<ScopeOperationResult<T>> ExecuteWithResultAsync<T>(Func<IServiceProvider, Task<T>> operation, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
// 参数验证
|
||||
|
if (operation == null) |
||||
|
{ |
||||
|
_logger.LogError("操作委托不能为空"); |
||||
|
return ScopeOperationResult<T>.Failure("操作委托不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (_serviceScopeFactory == null) |
||||
|
{ |
||||
|
_logger.LogError("服务作用域工厂未初始化"); |
||||
|
return ScopeOperationResult<T>.Failure("服务作用域工厂未初始化"); |
||||
|
} |
||||
|
|
||||
|
using var scope = _serviceScopeFactory.CreateScope(); |
||||
|
try |
||||
|
{ |
||||
|
// 检查取消令牌
|
||||
|
cancellationToken.ThrowIfCancellationRequested(); |
||||
|
|
||||
|
var result = await operation(scope.ServiceProvider); |
||||
|
|
||||
|
// 验证返回值(对于引用类型)
|
||||
|
if (result == null && typeof(T).IsClass && typeof(T) != typeof(string)) |
||||
|
{ |
||||
|
_logger.LogWarning("操作返回了null值,类型:{Type}", typeof(T).Name); |
||||
|
} |
||||
|
|
||||
|
return ScopeOperationResult<T>.Success(result); |
||||
|
} |
||||
|
catch (OperationCanceledException) |
||||
|
{ |
||||
|
_logger.LogInformation("作用域操作被取消"); |
||||
|
return ScopeOperationResult<T>.Failure("操作被取消"); |
||||
|
} |
||||
|
catch (ObjectDisposedException ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "服务作用域已被释放,无法执行操作"); |
||||
|
return ScopeOperationResult<T>.Failure("服务作用域已被释放"); |
||||
|
} |
||||
|
catch (InvalidOperationException ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "作用域操作无效:{Message}", ex.Message); |
||||
|
return ScopeOperationResult<T>.Failure($"作用域操作无效:{ex.Message}"); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "在执行作用域操作时发生未预期的错误:{Message}", ex.Message); |
||||
|
return ScopeOperationResult<T>.Failure($"执行操作时发生错误:{ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 安全地执行无返回值的作用域服务操作
|
||||
|
/// </summary>
|
||||
|
public async Task<ScopeOperationResult> ExecuteAsync(Func<IServiceProvider, Task> operation, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
// 参数验证
|
||||
|
if (operation == null) |
||||
|
{ |
||||
|
_logger.LogError("操作委托不能为空"); |
||||
|
return ScopeOperationResult.Failure("操作委托不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (_serviceScopeFactory == null) |
||||
|
{ |
||||
|
_logger.LogError("服务作用域工厂未初始化"); |
||||
|
return ScopeOperationResult.Failure("服务作用域工厂未初始化"); |
||||
|
} |
||||
|
|
||||
|
using var scope = _serviceScopeFactory.CreateScope(); |
||||
|
try |
||||
|
{ |
||||
|
// 检查取消令牌
|
||||
|
cancellationToken.ThrowIfCancellationRequested(); |
||||
|
|
||||
|
await operation(scope.ServiceProvider); |
||||
|
|
||||
|
return ScopeOperationResult.Success(); |
||||
|
} |
||||
|
catch (OperationCanceledException) |
||||
|
{ |
||||
|
_logger.LogInformation("作用域操作被取消"); |
||||
|
return ScopeOperationResult.Failure("操作被取消"); |
||||
|
} |
||||
|
catch (ObjectDisposedException ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "服务作用域已被释放,无法执行操作"); |
||||
|
return ScopeOperationResult.Failure("服务作用域已被释放"); |
||||
|
} |
||||
|
catch (InvalidOperationException ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "作用域操作无效:{Message}", ex.Message); |
||||
|
return ScopeOperationResult.Failure($"作用域操作无效:{ex.Message}"); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
_logger.LogError(ex, "在执行作用域操作时发生未预期的错误:{Message}", ex.Message); |
||||
|
return ScopeOperationResult.Failure($"执行操作时发生错误:{ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue