Как определить, завершен ли предыдущий вызов задачиC#

Место общения программистов C#
Ответить
Anonymous
 Как определить, завершен ли предыдущий вызов задачи

Сообщение Anonymous »

У меня есть приложение .NET 8 wpf, которое использовало набор инструментов сообщества Microsoft для MVVM и внедрения зависимостей расширений Microsoft, а также платформу EF-Core. В дополнение к представлениям и моделям представлений у меня есть класс Repo, который использует асинхронные сообщения для запроса данных с помощью EF-Core.

Приложение создает представление списка, и пользователь щелкает элемент, что вызывает изменение свойства элемента. и вызывает асинхронный метод в репозитории, который извлекает запись из базы данных.
Проблема возникает, если пользователь выбирает новый элемент до того, как был получен предыдущий элемент (т. е. он щелкнул не тот элемент и хочет щелкнуть по нему). еще один). Я получаю сообщение об ошибке «Вторая операция была начата в этом экземпляре контекста до завершения предыдущей операции».
Я пробовал изменить контекст данных и области службы, но это не решило проблему. Давайте сохраним этот вопрос для другой темы.

В этом сценарии новый вызов асинхронного метода выполняется всякий раз, когда пользователь меняет выбранный элемент. Как я могу определить, был ли завершен предыдущий вызов, прежде чем выполнять новый вызов?
Решение, которое я реализовал, установив свойство внутри метода, которое определяет, завершена ли задача, работает, но есть ли лучший способ определить, выполнена ли задача? Могу ли я заставить новый запрос дождаться завершения предыдущей задачи или отменить предыдущую задачу и начать новую. (Любой сценарий достаточен для нужд приложений, поскольку, как только пользователь нажимает на новый элемент, предыдущий элемент не имеет значения).
Приложены, по моему мнению, соответствующие фрагменты кода App.cs , ViewModel и Repo.

Код: Выделить всё

public partial class App : Application
{
public IServiceProvider serviceProvider { get; set; }

public App()
{
serviceProvider = CreateServiceProvider();
}

public new static App Current => (App)Application.Current;

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
}

private IServiceProvider CreateServiceProvider()
{
IServiceCollection services = new ServiceCollection();
services.AddDbContext(options => { options.UseSqlServer("defaultconnstring"); },ServiceLifetime.Transient);

services.AddTransient();
services.AddTransient();
return services.BuildServiceProvider();
}
}

Код: Выделить всё

public partial class ViewModel : ObservableObject
{
private ILocalRepo _localRepo;
private bool _taskcompleted = true;

[ObservableProperty]
private short ubCounter;

[ObservableProperty]
private short selectedCounter;

async partial void OnSelectedCounterChanged(short value)
{

await getSelectedResearch(value);
}

async partial void OnUbCounterChanged(short value)
{
await getSelectedResearch(value);
}

async internal Task getSelectedResearch(short value)
{
if (!_taskcompleted)
{
await Task.Delay(1500);
}
_taskcompleted = false;
SelectedResearch = await _localRepo.OneResearchbyCounter(value);
_taskcompleted = true;
}

public ResearchViewModelC1()
{
_localRepo = App.Current.serviceProvider.GetService();
}
}

Код: Выделить всё

public class LocalRepo : ILocalRepo
{
private readonly bardv2hContext _localdb;

public LocalRepo(bardv2hContext localdb)
{
_localdb = localdb;
}

public async Task OneResearchbyCounter(short counter)
{
var res = await _localdb.Researches
.Where(r=>r.Counter == counter)
.Include(r=>r.Inres)
.Include(r=>r.ApprovedResearch)
.Include(r=>r.Actualpayments)
.Include(r=>r.FiscalReports)
.Include(r=>r.Scireports)
.FirstOrDefaultAsync()
.ConfigureAwait(false);
return res;
}
}
Я попробовал использовать DBContextFactory на основе этого примера, но не смог заставить его работать. Я изменил свой app.cs на этот:

Код: Выделить всё

public partial class App : Application
{
public IServiceProvider serviceProvider { get; set; }

public App()
{
serviceProvider = CreateServiceProvider();
}

public new static App Current => (App)Application.Current;

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
}

private IServiceProvider CreateServiceProvider()
{
IServiceCollection services = new ServiceCollection();
services.AddDbContextFactory(options => { options.UseSqlServer("defaultconnstring"); });

services.AddTransient();
services.AddTransient();
return services.BuildServiceProvider();
}
}
И репозиторий к этому:

Код: Выделить всё

public LocalRepoWF(Func localdb)
{
_factory = localdb;
dbContext _localdb;
} public LocalRepoWF(Func localdb)
{
_factory = localdb;
}
public async Task selModel(string InvCode)
{
using (var _localdb = _factory.Invoke())
{ return await _localdb.Model.Find(InvCode); }
}
Но я получаю сообщение об ошибке.

Невозможно разрешить службу для типа «System.Func`1[dbContext]» при
пытаясь активировать LocalRepoWF

Я пытался зарегистрировать службу следующим образом:

Код: Выделить всё

    .AddScoped(lr => new LocalRepoWF(() => lr.GetService()))
Но при вызове процедуры в репозитории я получаю сообщение об ошибке: «Невозможно получить доступ к удаленному экземпляру контекста. Распространенной причиной этой ошибки является удаление экземпляра контекста, который был разрешен в результате внедрения зависимостей». а затем позже попытаться использовать тот же экземпляр контекста в другом месте вашего приложения."


Подробнее здесь: https://stackoverflow.com/questions/791 ... -completed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»