diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThread.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThread.cs index a46727e0e11..8a34f405dd8 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThread.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThread.cs @@ -11,7 +11,7 @@ namespace System.Windows.Input internal sealed class PenThread { - private PenThreadWorker _penThreadWorker; + private readonly PenThreadWorker _penThreadWorker; internal PenThread() { @@ -37,13 +37,14 @@ internal void Dispose() private void DisposeHelper() { - // NOTE: PenThreadWorker deals with already being disposed logic. - _penThreadWorker?.Dispose(); + _penThreadWorker.Dispose(); GC.KeepAlive(this); } ///////////////////////////////////////////////////////////////////// + internal bool IsDisposed => _penThreadWorker.IsDisposed; + internal bool AddPenContext(PenContext penContext) { return _penThreadWorker.WorkerAddPenContext(penContext); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadPool.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadPool.cs index b2673c26e8a..fd42deca801 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadPool.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadPool.cs @@ -93,20 +93,15 @@ private PenThread GetPenThreadForPenContextHelper(PenContext penContext) // We scan back to front to enable list cleanup. for (int i = _penThreadWeakRefList.Count - 1; i >= 0; i--) { - PenThread candidatePenThread = null; - - // Select a thread if it's a valid WeakReference and we're not ignoring it - // Allow selection to happen multiple times so we get the first valid candidate - // in forward order. - if (_penThreadWeakRefList[i].TryGetTarget(out candidatePenThread) - && !ignoredThreads.Contains(candidatePenThread)) + // Check if the WeakReference is still alive and not disposed. + if (!_penThreadWeakRefList[i].TryGetTarget(out PenThread candidatePenThread) || + candidatePenThread.IsDisposed) { - selectedPenThread = candidatePenThread; + _penThreadWeakRefList.RemoveAt(i); } - // This is an invalid WeakReference and should be removed - else if (candidatePenThread == null) + else if (!ignoredThreads.Contains(candidatePenThread)) { - _penThreadWeakRefList.RemoveAt(i); + selectedPenThread = candidatePenThread; } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadWorker.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadWorker.cs index a873eeb5860..b0787c4d8b8 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadWorker.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenThreadWorker.cs @@ -559,8 +559,15 @@ internal bool WorkerRemovePenContext(PenContext penContext) ///////////////////////////////////////////////////////////////////// + internal bool IsDisposed => __disposed; + internal TabletDeviceInfo[] WorkerGetTabletsInfo() { + if (__disposed) + { + return Array.Empty(); + } + // Set data up for this call WorkerOperationGetTabletsInfo getTablets = new WorkerOperationGetTabletsInfo();