UOW-вторая операция, начатая в этом контексте до завершения предыдущей асинхронной операции

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

логика навигации: здесь нет проблем

public void OnNavigatedTo(NavigationContext navigationContext)
{
    int relatieId = (int)navigationContext.Parameters["RelatieId"];
    if (_relatie != null && _relatie.RelatieId == relatieId) return;

    loadRelatieAsync(relatieId);
}

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
    bool navigationAllowed = true;
    continuationCallback(navigationAllowed);
}

логика глубокой загрузки:

private async Task loadRelatieAsync(int relatieId)
{
    try
    {
        await Task.Run(async () =>
        {

            _unitOfWork = _UnitOfWorkFactory.createUnitOfWorkAsync();

            IEnumerable<Relatie> relaties = await getRelatieAsync(_unitOfWork, relatieId).ConfigureAwait(true);

            _relatieTypeTypes = await getRelatieTypeTypesAsync(_unitOfWork, relatieId).ConfigureAwait(true);
            _relatie = relaties.FirstOrDefault();

            _unitOfWork.Dispose();
        }).ConfigureAwait(true);

        processRelatie(_relatie);

        processRelatieTypes(_relatie, _relatieTypeTypes);
    }
    catch (Exception Ex)
    {

        MessageBox.Show(Ex.Message);
        throw;
    }

}

private async Task<IEnumerable<Relatie>> getRelatieAsync(IUnitOfWorkAsync unitOfWork, int relatieId)
{

    IEnumerable<Relatie> relaties = null;
    try
    {
        IRepositoryAsync<Relatie> relatieRepository = unitOfWork.RepositoryAsync<Relatie>();
        relaties = await relatieRepository
            .Query(r => r.RelatieId == relatieId)
            .Include(i => i.BegrafenisOndernemer)
            .SelectAsync()
            .ConfigureAwait(false);

        IRepositoryAsync<Adres> adresRepository = unitOfWork.RepositoryAsync<Adres>();
        //exception is thrown after executing following line
        var adressen = await adresRepository
            .Query(r => r.RelatieId == relatieId)
            .Include(i => i.AdresType)
            .SelectAsync()
            .ConfigureAwait(false);
        _relatieTypeRepository = unitOfWork.RepositoryAsync<RelatieType>();
        var relatieTypes = await _relatieTypeRepository
            .Query(r => r.RelatieId == relatieId)
            .SelectAsync()
            .ConfigureAwait(false);
    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);//exception is shown here
        throw;
    }
    return relaties;
}

private async Task<IEnumerable<RelatieTypeType>> getRelatieTypeTypesAsync(IUnitOfWorkAsync unitOfWork, int relatieId)
{

    IEnumerable<RelatieTypeType> relatieTypeTypes = null;
    try
    {
        IRepositoryAsync<RelatieTypeType> relatieTypeTypeRepository =
            unitOfWork.RepositoryAsync<RelatieTypeType>();

        relatieTypeTypes = await relatieTypeTypeRepository
            .Query()
            .SelectAsync()
            .ConfigureAwait(false);

    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
        throw;
    }
    return relatieTypeTypes;
}

Я получение исключений, как будто я забыл ждать,но это никогда не бывает. Я также использую configureawait(true) правильно, когда я хочу продолжения в потоке GUI. Но я продолжаю получать эту ошибку в логике deeploading. Единица работы и классы репозитория также используют механизм async await, но и там я жду должным образом.

вторая операция началась в этом контексте до завершения предыдущей асинхронной операции. Используйте 'await' для обеспечения асинхронных операций завершили перед вызовом другого метода в этом контексте. Члены экземпляров не гарантируется потокобезопасность.

редактировать (удален код регистратора для уменьшения размера кода)

2 ответов


проблема заключается в следующем коде:

_unitOfWork = _UnitOfWorkFactory.createUnitOfWorkAsync();

IEnumerable<Relatie> relaties = await getRelatieAsync(_unitOfWork, relatieId).ConfigureAwait(true);

_relatieTypeTypes = await getRelatieTypeTypesAsync(_unitOfWork, relatieId).ConfigureAwait(true);
_relatie = relaties.FirstOrDefault();

 _unitOfWork.Dispose();

UnitOfWork является переменной экземпляра, когда сценарий запускается во второй раз, он перезаписывается новым экземпляром. Затем уже выполняемый сценарий использует этот новый UnitOfWork вместо своего собственного, поскольку он перезаписан. Не так легко определить, но простое состояние гонки. Я нашел его, заменив все переменные, локальные переменные и тогда проблема disappaered.


Это, вероятно, не ответ, но общий взгляд на ваш код.

основная цель async / await-сохранить текущий поток доступным. Это помогает не блокировать поток пользовательского интерфейса и поддерживать отзывчивость приложения.

вы уже убедитесь, что ваша глубокая загрузка происходит в потоке ThreadPool, потому что вы начинаете его полностью использовать задач.Run (). Вероятно, вы можете обойти большинство своих проблем, используя значение по умолчанию синхронные методы EntityFramework в вашем механизме загрузки.

на первый взгляд, ваш код выглядит штраф в размере на асинхронные вызовы. Может быть, ваша глубокая загрузка запускается несколько раз?