Как ItemPeersStorage может генерировать исключение при получении значения из WeakDictionary? - PullRequest
0 голосов
/ 01 ноября 2019

Я получил следующее исключение через автоматическое создание отчетов об исключениях, поэтому у меня не так много контекста. Похоже, что приложение показало представление с несколькими элементами управления, DataGrid является единственным ItemsControl. Приложение использует сенсорный экран, и я предполагаю, что tabtip.exe может вызвать вызов AutomationPeer, потому что я не использую никакой автоматизации пользовательского интерфейса в явном виде. Похоже, что исключение произошло через 30 минут без какого-либо взаимодействия с пользователем.

Я нацеливаюсь на .NET Framework 4.7.2, но на компьютере установлен .NET Framework 4.8.

Кто-нибудь виделэто раньше? Любые намеки на то, почему это произойдет?

Unhandled exception occurred. Origin=System.Windows.Dispatcher.CurrentDispatcher.UnhandledException:
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at MS.Internal.WeakDictionary`2.get_Item(TKey key)
   at System.Windows.Automation.Peers.ItemPeersStorage`1.get_Item(Object item)
   at System.Windows.Automation.Peers.ItemsControlAutomationPeer.GetPeerFromWeakRefStorage(Object item)
   at System.Windows.Automation.Peers.ItemsControlAutomationPeer.AddProxyToWeakRefStorage(WeakReference wr, ItemAutomationPeer itemPeer)
   at System.Windows.Automation.Peers.ItemAutomationPeer.AddToParentProxyWeakRefCache()
   at MS.Internal.Automation.ElementProxy.StaticWrap(AutomationPeer peer, AutomationPeer referencePeer)
   at System.Windows.Automation.Peers.AutomationPeer.UpdateChildrenInternal(Int32 invalidateLimit)
   at System.Windows.Automation.Peers.AutomationPeer.UpdateChildren()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
   at System.Windows.ContextLayoutManager.fireAutomationEvents()
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Метод System.Windows.Automation.Peers.ItemPeersStorage1.get_Item(Object item) из From .NET Framework 4.8 Справочный источник Я не вижу, как это могло произойти? Он проверяет ContainsKey() перед доступом к WeakDictionary.

public T this[object item]
{
    get
    {
        if (_count == 0 || item == null)
            return default(T);

        if (_usesHashCode)
        {
            if (_hashtable == null || !_hashtable.ContainsKey(item))
                return default(T);

            return _hashtable[item] as T;
        }
        else
        {
            if (_list == null)
                return default(T);

            for (int i = 0; i < _list.Count; i++)
            {
                KeyValuePair<object, T> pair = _list[i];
                if (Object.Equals(item, pair.Key))
                    return pair.Value;
            }

            return default(T);
        }
}

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Я скачал код для .NET Framework 4.7.2 из ссылочного источника , и похоже, что в этой версии есть ошибка, поскольку они НЕ проверяют ContainsKey ():

get
{
    if (_count == 0 || item == null)
        return default(T);

    if (_usesHashCode)
    {
        if (_hashtable == null)
            return default(T);

        return _hashtable[item] as T;
    }
    else
    {
        if (_list == null)
            return default(T);

        for (int i = 0; i < _list.Count; i++)
        {
            KeyValuePair<object, T> pair = _list[i];
            if (Object.Equals(item, pair.Key))
                return pair.Value;
        }

        return default(T);
    }
}

Поскольку я нацеливаюсь на .NET Framework 4.7.2 и использую элемент конфигурации <supportedRuntime/>, я не использую код .NET Framework 4.8, который я предполагал сначала.

Итак, ошибка исправлена. NET Framework 4.8. Я полагаю, что вместо этого я нацелусь на эту версию.

0 голосов
/ 01 ноября 2019

Пожалуйста, посмотрите на WeakDictionary Source , который используется внутренне ItemPeersStorage, и вы заметите, что он выдает исключение для ключей, которые не содержатся.

public TValue this[TKey key]
    {
        get
        {
            if (!_hashTable.ContainsKey(key))
            {
                throw new KeyNotFoundException();
            }
            return (TValue)_hashTable[key];
        }
        set
        {
            _hashTable.SetWeak(key, value);
        }
    }
...