I have a method in a viewmodel that updates an observablecollection (Indicators) every time data is sent from the Binance Api. However, if I remove the last item from that list (pressing a button on the app multiple times, or even once at the critical time), I can get an index out of range error. The program will continue only if I catch the error, but I cannot figure out a mechanism to avoid the error in the first place.
public MainViewModel()
{
//this command starts the Api stream from Binace.
UpdateAllCommand = new Command(async () => await this.UpdateAll());
//this command removes the last item from the list
RemoveIndicatorCommand = new Command(this.RemoveIndicator);
}
async Task UpdateAll()
{
var result = await this.socketClient.UsdFuturesApi.SubscribeToMiniTickerUpdatesAsync(this.Symbol, async data =>
{
//Update Indicators everytime data is streamed
if (this.Indicators != null && this.Indicators.Count > 0)
{
for (int i = 0; i < this.Indicators.Count; i++)
{
if (i < this.Indicators.Count)
{
try
{
var values = await GetIndicator(this.Indicators[i].Name, this.Indicators[i].Period);
this.Indicators[i].Value = values[^1];
}
catch (Exception ex)
{
...
}
}
}
}
});
}
}
void RemoveIndicator()
{
if (this.Indicators.Count > 0)
{
this.Indicators.RemoveAt(this.Indicators.Count - 1);
}
}
I am aware that if I try to remove items from a collection while it's updating and looping, I can get index out of range error. But how could I safely remove it without error? I have try to use lock or semaphoreslim but with no results. My approach could be wrong all together, but please help me with a hint. Thank You!
Your question is about how to remove an item from a continuously updating collection and one short fix to try would be getting the last item using
Linqinstead of an index.LastOrDefault()will either retrieve an item or it won'tnullit isn't going to attempt to remove.And yes, your intuition to put a lock around the above block is probably a good one.
Better still, you might want to experiment with something like this if you haven't already: