c# - 我应该处理 IServiceProvider 提供的瞬态对象还是垃圾收集器处理它?
问题描述
我正在构建一个锦标赛应用程序,其中当然有很多锦标赛可以玩。我从 ASP.NET Core 3.1 中的内置依赖注入中获取了一个 TournamentStore 对象。
在 Startup.cs 的 ConfigureServices 方法中,我设置了一个临时服务:
services.AddTransient<ITournamentStore, TournamentStore>();
我通过在 TournamentService 类的构造函数中注入 IServiceProvider 来获得该服务:
public class TournamentService : ITournamentService
{
private readonly IServiceProvider _serviceProvider;
public TournamentService(
IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task<ITournamentStore> GetRandomTournamentAsync(DateTime startTime)
{
var tournament = (ITournamentStore)_serviceProvider.GetService(typeof(ITournamentStore));
// add tournament details...
在 TournamentStore (我从 IServiceProvider 获得的服务)中,我正在使用 System.Timers.Timer 应该被处理:
public class TournamentStore : ITournamentStore, IAsyncDisposable, IDisposable
{
private Timer _timer;
private readonly ITournamentsStore _tournaments;
private readonly IHubContext<GameHub, IGameClient> _hubContext;
private readonly IMapper _mapper;
public TournamentStore(
ITournamentsStore tournaments,
IHubContext<GameHub, IGameClient> hubContext,
IMapper mapper)
{
_tournaments = tournaments;
_hubContext = hubContext;
_mapper = mapper;
}
public string PublicId { get; set; } = Guid.NewGuid().ToString();
public string Name { get; set; }
public string Category { get; set; }
public int? CategoryId { get; set; }
public string Type { get; set; }
public string TypeId { get; set; }
public string Difficulty { get; set; }
public string DifficultyId { get; set; }
public List<QuestionModel> Questions { get; set; }
public int NumberOfQuestions => Questions.Count();
public int SecondsPerQuestion { get; set; } = 15;
public int CurrentQuestion { get; set; } = 0;
public bool Finshed => CurrentQuestion > Questions.Count();
public bool Public { get; set; }
public DateTime StartTime { get; set; }
public string StartTimeWithTimeZone => StartTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
public DateTime? EndTime { get; set; }
public List<Player> Players { get; set; }
public int NumberOfPlayers => Players.Count();
public void SetTournamentStartTimer()
{
var difference = StartTime - DateTime.UtcNow;
_timer = new Timer(difference.TotalMilliseconds);
_timer.Elapsed += async (sender, e) => await StartTournamentAsync();
_timer.Start();
}
private async Task StartTournamentAsync()
{
// some logic to start tournament
}
public ValueTask DisposeAsync()
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
所以我想知道我应该在 DisposeAsync 方法中处理完整对象还是只处理 Timer 并让垃圾收集器处理 TournamentStore 对象?如您所见,TournamentStore 对象由多个属性和两个对象列表组成,所以如果我要处理 TournamentStore 对象,是否应该将这些列表设置为 null?如果没有足够的玩家或锦标赛结束,将从对象本身调用 DisposeAsync。
解决方案
向服务提供者请求 ITournamentStore 的类不知道对象的范围(单例、瞬态等),因此 TournamentStore 的处置应由 ServiceProvider 管理。
TournamentStore 的所有可处置属性都应在 TournamentStore 处置中处置。无需将所有属性设置为空。
我建议不要同时实现接口 IDisposable 和 IAsyncDisposable。Dispose 或 DisposeAsync 方法旨在由创建 TournamentStore 的对象调用(此处为 ServiceProvider)。
我建议使用如下实现:
private async Task<ITournament> StartTournamentAsync()
和
ITournament : IAsyncDisposable
推荐阅读
- c# - 使用 Amazon.Lambda.TestTool-3.1 (.NET) 时找不到 Libuv 1.10.0 dll
- javascript - 我的网页无法从我的 firebase 实时数据库片段中找到链接
- android - AWS Pinpoint - Amplify - Android - 自定义事件记录在控制台中,但无法通过它们进行过滤
- vb.net - 如何将localdb连接到水晶报表
- c# - 使用 EF Core 和 C# 使用 PgSql 进行 Sql 参数化
- java - 在容器周围移动标签时出现 JavaFX 异常。(IndexOutOfBoundsException)
- python - 从 Python 的 fortran 获取两个值?
- python - 在python中使用table_id和beautifulsoup来提取数据
- reactjs - 如何在不渲染子组件的情况下处理删除按钮
- python - Tensorflow 错误:'RepeatedCompositeFieldContainer' 对象没有属性 'append'