gpt4 book ai didi

c# - UOW - 在上一个异步操作完成之前,第二个操作在此上下文中开始

转载 作者:可可西里 更新时间:2023-11-01 08:07:26 26 4
gpt4 key购买 nike

我正在尝试下面的代码,它有两个部分,一个是通过棱镜导航。当允许导航时,我会异步启动深度加载,但每次都有一个新的上下文。在后面的代码中,我想取消未完成此加载的挂起导航,但下面的代码甚至不起作用,所以取消是以后的事;-)

导航逻辑:这里没有问题

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;
}

我一直收到异常,就好像我忘记等待一样,但事实并非如此。每当我想在 GUI 线程上继续时,我也会正确地使用 configureawait(true) 。但是我在深度加载逻辑中不断收到这个错误。工作单元和存储库类也使用异步等待机制,但我也在适本地等待。

在上一个异步操作完成之前,第二个操作开始在此上下文中。使用“await”确保所有异步操作在调用此上下文的另一个方法之前已完成。不保证任何实例成员都是线程安全的。

编辑(删除记录器代码以减小代码大小)

最佳答案

问题是这段代码:

_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 而不是它自己的,因为它被覆盖了。不是那么容易发现,而是一个简单的竞争条件。我通过将所有实例变量替换为局部变量找到了它,然后问题就消失了。

关于c# - UOW - 在上一个异步操作完成之前,第二个操作在此上下文中开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28331244/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com