FromResult или IServiceScopeFactory в серверной части Blazor - PullRequest
2 голосов
/ 16 октября 2019

Итак, я вставлял 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. Поэтому, если я, например, вызову return await db.SomeTable.Where (x => x.Id == id) .ToListAsync ();без IServiceScopeFactory он будет жить, пока вы не закроете веб-сайт. Таким образом, это создает ошибку: «Вторая операция началась в этом контексте до завершения предыдущей операции».

1 Ответ

1 голос
/ 16 октября 2019

Вы не можете сравнивать эти два параметра, поскольку они не имеют ничего общего.

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. Я написал пост в блоге , если вы хотите узнать больше.

...