因此,我一直在向页面注入IServiceScopeFactory以便在通过EF Core获取数据时使用它的作用域。 但是昨天我偶然发现有人在调用数据库时使用Task.FromResult。 是一个比另一个更好的选择吗?
提前谢谢!
Ex Task.FromResult
//In code behind
[Inject]
IMyService myService { get; set; }
protected void GetSomeData()
{
var someData = await myServie.GetSomeData();
}
//From serviceClass
public async Task<List<SomeData>> GetSomeData(int id)
{
return await Task.FromResult(db.SomeTable.Where(x => x.Id == qualifierVersionId).AsEnumerable());
}
Ex
//In code behind
[Inject]
IServiceScopeFactory ScopeFactory { get; set; }
protected void GetSomeData()
{
using (var serviceScope = ScopeFactory.CreateScope())
{
var myService = serviceScope.ServiceProvider.GetService<IMyService>();
var someData = await myServie.GetSomeData();
}
}
//From serviceClass
public async Task<List<SomeData>> GetSomeData(int id)
{
return await db.SomeTable.Where(x => x.Id == id).ToListAsync();
}
编辑(因为为什么我想知道该走哪条路的问题)
我需要使用其中一个,因为在使用服务器端Blazor时,寿命使Scoop的行为类似于Singleton。因此,如果我例如致电返回等待db.SomeTable.Where(x => x.Id == id).ToListAsync();如果没有IServiceScopeFactory,它将一直存在,直到您关闭网站为止。因此,这会产生一个错误:“在上一个操作完成之前,第二个操作是在此上下文上开始的。”
答案 0 :(得分:1)
您无法将两者进行比较,因为它们没有共同点。
Task.FromResult只会创建一个成功完成且具有指定结果的任务。我相信使用Task.FromResult的主要用例之一是实现异步接口但实现是同步的,如上例所示。在数据库调用上,这并不是一个好主意,因为它们可能需要很长时间。
我不确定您为什么使用上面的IServiceScopeFactory
。如果是这样,那么您所请求的服务的范围仅限于您所请求的组件的生存期,那么有一种更好的方法。
public class MyComponent : OwningComponentBase<IMyService>
{
protected void GetSomeData(int id)
{
var someData = await Service.GetSomeData(id);
}
}
public class MyService : IMyService
{
public async Task<List<SomeData>> GetSomeData(int id)
{
return await db.SomeTable.Where(x => x.Id == id).ToListAsync();
}
}
通过使用OwningComponentBase,可以在幕后为您创建服务范围,并且基础组件可以通过Service
属性来公开该服务。如果您想了解更多,我已经written a blog post在上面。