出于演示目的,假设我有一个名为StateManager的类:
public class StateManager
{
public StateManager()
{
IsRunning = false;
}
public void Initialize()
{
Id = Guid.NewGuid().ToString();
IsRunning = true;
KeepSession();
}
public void Dispose()
{
Id = null;
IsRunning = false;
}
public string Id { get; private set; }
public bool IsRunning { get; private set; }
private async void KeepSession()
{
while(IsRunning)
{
Console.WriteLine($"{Id} checking in...");
await Task.Delay(5000);
}
}
}
它具有一种在启动后运行的方法,该方法每5秒将其ID写入控制台。
在启动类中,将其添加为范围服务:
services.AddScoped<StateManager>();
也许我使用的位置错误,但是在我的 Mainlayout.razor 文件中,我在 OnInitializedAsync()
上对其进行了初始化。@inject Models.StateManager StateManager
...
@code{
protected override async Task OnInitializedAsync()
{
StateManager.Initialize();
}
}
在呈现第一页后运行该应用程序时,控制台输出显示正在运行2个实例:
bcf76a96-e343-4186-bda8-f7622f18fb27正在检入...
e5c9824b-8c93-45e7-a5c3-6498b19ed647正在检入...
如果我在对象上运行 Dispose(),它将在一个实例上结束 KeepSession() while循环,而另一个实例继续运行。如果我运行 Initialize(),则会出现一个新实例,并且每次我运行 Initialize()时,都会生成新实例,并且它们都将使用其唯一ID写入控制台。我可以无限创建任意数量的内容。
我以为将Scoped 服务注入DI可以确保每个电路有该对象的单个实例?我还尝试在 OnAfterRender()覆盖范围内进行初始化,以防预渲染过程创建双重实例(尽管这不能解释为什么我可以在注入了服务的页面中创建如此多的实例)。
是否存在无法正确处理的问题?除了Mainlayout之外,还有没有更好的位置初始化StateManager?