如何防范Blazor wasm中异步方法的双重触发
How to guard against double trigger of async method in Blazor wasm
我正在开发一个 blazor wasm 应用程序。我正在努力解决异步问题 - 我发现很难解决,因为浏览器中的线程对我来说并不完全清楚。我没有使用任何异步空隙 - 一切都是异步任务。
从 API 调用(异步)我得到了两个对象。一个对象作为同步更新分派到 fluxor store,另一个我必须在本地 Indexdb 上进行异步调用,之后这个对象也进入 fluxor store。
这两个 fluxor store updates 通过事件触发 view model 的更新方法。此更新方法是异步的,因为它还从 IndexedDb 获取一些信息。此异步方法从 Indexdb 异步获取一些项目,清除字典,然后枚举 属性 的 fluxor 存储以更新模型。
此方法被快速连续调用两次,结果开始交织。
问题是第一个方法调用在状态枚举期间暂停,接下来第二个方法调用清除字典,并开始它自己的枚举(并完成),之后第一个方法在它更早开始的时候恢复枚举。
这会导致错误 - 尝试将相同的键添加到字典中两次。
如何防范?
如何防止相同的方法调用在 Blazor wasm 中与自身交织?
如何暂停异步更新方法的(同步)枚举部分,允许完整方法 运行,然后再次恢复第一次调用?
public partial class DebugPage : BasePage, IDisposable
{
[Inject] IState<MonthBalanceState> MonthBalanceState { get; set; }
private Dictionary<IMonthBalanceAddress, int> DbCountDictionary = new Dictionary<IMonthBalanceAddress, int>();
protected override async Task OnParametersSetAsync()
{
MonthBalanceState.StateChanged += async (_, _) => await MonthBalanceState_StateChanged();
Console.WriteLine($"Linkage made to Monthbalance State");
await base.OnParametersSetAsync();
}
//This method get's called twice quickly - starting the interweaving
private async Task MonthBalanceState_StateChanged()
{
Console.WriteLine($"Update via Statechanged Monthbalance State");
var result = await UpdateDictionaryAsync();
}
private async Task<bool> UpdateDictionaryAsync()
{
DbCountDictionary.Clear();
Log.Debug("Debug dictionary updated");
foreach (IMonthBalanceLoadable mb in MonthBalanceState.Value.MonthBalances.ToList())
{
Console.WriteLine($"Adding {mb.Address.ToString()}");
DbCountDictionary.Add(mb.Address, await Db.GetCountByAddress(mb.Address));
}
return true;
}
如果可能,您可以使用 OnAfterRenderAsync(bool firstRender) 而不是 OnParametersSetAsync(),然后仅在它是第一个渲染时才设置变量。
+= async (_, _) => await MonthBalanceState_StateChanged();
此 lambda 是 async void
包装您的处理程序。
所以没有等待整体,这就是问题的根源。
StateChanged 事件可能应该是一个 EventCallback 属性。 Post 如果您需要更多帮助,请查看相关代码。
我正在开发一个 blazor wasm 应用程序。我正在努力解决异步问题 - 我发现很难解决,因为浏览器中的线程对我来说并不完全清楚。我没有使用任何异步空隙 - 一切都是异步任务。
从 API 调用(异步)我得到了两个对象。一个对象作为同步更新分派到 fluxor store,另一个我必须在本地 Indexdb 上进行异步调用,之后这个对象也进入 fluxor store。
这两个 fluxor store updates 通过事件触发 view model 的更新方法。此更新方法是异步的,因为它还从 IndexedDb 获取一些信息。此异步方法从 Indexdb 异步获取一些项目,清除字典,然后枚举 属性 的 fluxor 存储以更新模型。
此方法被快速连续调用两次,结果开始交织。
问题是第一个方法调用在状态枚举期间暂停,接下来第二个方法调用清除字典,并开始它自己的枚举(并完成),之后第一个方法在它更早开始的时候恢复枚举。
这会导致错误 - 尝试将相同的键添加到字典中两次。
如何防范? 如何防止相同的方法调用在 Blazor wasm 中与自身交织? 如何暂停异步更新方法的(同步)枚举部分,允许完整方法 运行,然后再次恢复第一次调用?
public partial class DebugPage : BasePage, IDisposable
{
[Inject] IState<MonthBalanceState> MonthBalanceState { get; set; }
private Dictionary<IMonthBalanceAddress, int> DbCountDictionary = new Dictionary<IMonthBalanceAddress, int>();
protected override async Task OnParametersSetAsync()
{
MonthBalanceState.StateChanged += async (_, _) => await MonthBalanceState_StateChanged();
Console.WriteLine($"Linkage made to Monthbalance State");
await base.OnParametersSetAsync();
}
//This method get's called twice quickly - starting the interweaving
private async Task MonthBalanceState_StateChanged()
{
Console.WriteLine($"Update via Statechanged Monthbalance State");
var result = await UpdateDictionaryAsync();
}
private async Task<bool> UpdateDictionaryAsync()
{
DbCountDictionary.Clear();
Log.Debug("Debug dictionary updated");
foreach (IMonthBalanceLoadable mb in MonthBalanceState.Value.MonthBalances.ToList())
{
Console.WriteLine($"Adding {mb.Address.ToString()}");
DbCountDictionary.Add(mb.Address, await Db.GetCountByAddress(mb.Address));
}
return true;
}
如果可能,您可以使用 OnAfterRenderAsync(bool firstRender) 而不是 OnParametersSetAsync(),然后仅在它是第一个渲染时才设置变量。
+= async (_, _) => await MonthBalanceState_StateChanged();
此 lambda 是 async void
包装您的处理程序。
所以没有等待整体,这就是问题的根源。
StateChanged 事件可能应该是一个 EventCallback 属性。 Post 如果您需要更多帮助,请查看相关代码。