Dav*_*ave 6 .net observablecollection thread-safety tolist
我有一个ObservableCollection日志,我通过属性绑定到我的GUI
public ObservableCollection<ILog> Logs {get; private set;}
Run Code Online (Sandbox Code Playgroud)
需要在其他地方显示日志的子集,所以我有:
public ObservableCollection<ILog> LogsForDisplay
{
get
{
ObservableCollection<ILog> displayLogs = new ObservableCollection<ILog>();
foreach (Log log in Logs.ToList()) // notice the ToList()
{
if (log.Date != DateTime.Now.Day)
continue;
displayLogs.Add(log);
}
return displayLogs;
}
Run Code Online (Sandbox Code Playgroud)
在我添加"ToList()"之前,我偶尔会遇到"收集被修改;枚举操作可能无法执行"的例外情况.有意义的是 - 当我迭代它时,有人可以添加到Logs.我从Collection中修改了"ToList"的想法; 枚举操作可能不会执行,这似乎表明ToList是要走的路,并暗示它的线程安全.但是ToList()线程安全吗?我假设在内部它必须使用列表并迭代它?如果有人同时添加该列表怎么办?仅仅因为我没有看到问题并不意味着没有问题.
我的问题.ToList()线程是否安全?如果没有,保护日志的最佳模式是什么?如果ToList()是线程安全的,你有引用吗?
奖金问题.如果要求改变,我需要在GUI上显示的是LogsForDisplay和NOT Logs,我可以将Logs更改为其他可以解决问题的东西吗?如ImmutableList?然后,我不必调用ToList <>,我认为这需要一些时间来制作副本.
如果我能提供澄清,请告诉我.谢谢,
戴夫
ToList扩展方法的实现归结为通过Array.Copy方法将项目从一个数组复制到另一个数组,虽然Collection was modified从您隐藏错误不是线程安全的,并且当在Array.Copy基准测试期间更改基础项目时您可能会遇到奇怪的行为.
我建议它CollectionView用于绑定,我在相似的情况下已经使用了很长时间,到目前为止没有遇到任何问题.
// somewhere in .ctor or other init-code
var logsForDisplay = new CollectionView(this.Logs);
logsForDisplay.Predicate = log => ((Log)log).Date == DateTime.Now.Day;
public CollectionView LogsForDisplay { get { return this.logsForDisplay; } }
Run Code Online (Sandbox Code Playgroud)
您可以使用另一个CollectionView用于不同的用例,例如:
// somewhere in .ctor or other init-code
var yesterdaysLogs = new CollectionView(this.Logs);
yesterdaysLogs.Predicate = log => ((Log)log).Date == DateTime.Now.AddDays(-1).Day;
public CollectionView YesterdaysLogs{ get { return this.yesterdaysLogs; } }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
606 次 |
| 最近记录: |