I wish to iterate over a collection in a thread safe manner. I find it’s convieniant to have one method called
/// <summary>
/// This visits all items and performs an action on them in a thread manner
/// </summary>
/// <param name="visitAction">The action to perform on the item</param>
public void VisitAllItems(Action<Item> visitAction) {
lock (listLock) {
foreach (Item item in this.ItemList) {
visitAction.Invoke(item);
}
}
}
An example of it’s use could be
/// <summary>
/// Saves each item in the list to the database
/// </summary>
protected static void SaveListToDatabase() {
this.VisitAllItems(item => {
bool itemSavedSuccessfully = item.SaveToDB();
if(!itemSavedSuccessfully) {
//log error message
}
});
}
Another example of it’s use would be
/// <summary>
/// Get the number of special items in the list.
/// </summary>
protected int GetNumberOfUnsynchronisedItems() {
int numberOfSpecialItems = 0;
this.VisitAllItems((item) => {
numberOfSpecialItems += item.IsItemSpecial() ? 1 : 0;
});
return numberOfSpecialItems;
}
But I’m sure there is a better way of writing the VisitAllItems method to use a Func<> rather than an Action<> delegate to return this value. I’ve tried several things but end up with compilation errors.
Can anyone see a neater way to implement this method?
Thanks,
Alasdair
It all depends on the usage, so it’s hard to tell what exactly would be useful for you. But one way would be to return one result for each item in the collection, and then use LINQ to combine the results.
Normally, I would use
yield returninstead of manually creating theList<T>, but I think it’s better this way here, because of thelock.The usage would be like this: