Fix Code Model race for real this time
I thought I'd fixed this subtle race with PR #8607. After all, the check-in tests were passing and it passed locally on my machine. However, it was still failing consistently on the build server. Finally, I noticed that the only test passes that were failing were on x86 *Release* (insert sound of forehead being smacked). After compiling Release, I could reproduce the problem locally. It turns out that this was a race with GC. In a previous fix, when adding an element to FileCodeModel's element cache, we would first check to see if the element was already in the cache. If it was in the cache, we'd remove it before adding it. However, the test to see if the element was in the cache called `CleanableWeakComHandleTable.TryGetValue(TKey key, out TValue value)`, which would only return true if `key` was in the cache and `value` was not set to null. In essence, it's defined like so: ```C# public bool TryGetValue(TKey key, out TValue value) { this.AssertIsForeground(); WeakComHandle<TValue, TValue> handle; if (_table.TryGetValue(key, out handle)) { value = handle.ComAggregateObject; return value != null; } value = null; return false; } ``` However, when running in Release, the GC can run a bit more aggresively and `handle.ComAggregatedObject` (a weak reference) could easily be null. The fix is to add a simpler `CleanableWeakComHandleTable.ContainsKey(TKey key)` and use that instead. ```C# public bool ContainsKey(TKey key) { this.AssertIsForeground(); return _table.ContainsKey(key); } ```
Showing
想要评论请 注册 或 登录