【问题标题】:Why closing window created in a unit-test raises an InvalidComObjectException?为什么在单元测试中创建的关闭窗口会引发 InvalidComObjectException?
【发布时间】:2013-06-16 04:07:29
【问题描述】:

当使用 MSTest 进行单元测试时,我创建了一个 WPF 窗口。当此窗口关闭时,Visual Studio 会显示 InvalidComObjectException:

COM object that has been separated from its underlying RCW cannot be used.

它在[TestMethod] 退出后 引发,并且堆栈只包含外部代码(没有InnerException)。这就是我所拥有的:

StackTrace:
       at System.Windows.Input.TextServicesContext.StopTransitoryExtension()
       at System.Windows.Input.TextServicesContext.Uninitialize(Boolean appDomainShutdown)
       at System.Windows.Input.TextServicesContext.TextServicesContextShutDownListener.OnShutDown(Object target, Object sender, EventArgs e)
       at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e)

DeclaringType:
    {Name = "TextServicesContext" FullName = "System.Windows.Input.TextServicesContext"}

    Assembly:
        {PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}

这是创建窗口的代码:

var myWindow = new SomeWindow(errors);
myWindow.ShowDialog();

窗口包含两个ListViews,其中包含一些文本元素和复选框

【问题讨论】:

    标签: c# wpf unit-testing exception dispatcher


    【解决方案1】:

    我前段时间偶然发现了这一点。如果我没记错的话,那是因为在测试之间您的 AppDomain 的默认 Dispatcher 没有正确清理和重新初始化。

    为了解决这个问题,我创建了一个 DomainNeedsDispatcherCleanup 属性类,负责正确设置和拆卸 Dispatcher。我会在找到它后立即将其包含在此处,但请注意我使用的是 XUnit,而不是 MSTest。

    编辑:刚刚找到它。给你:

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Threading;
    using Xunit;
    
    namespace Boost.Utils.Testing.XUnit.WPF
    {
        /// <summary>helful if you stumble upon 'object disconnected from RCW' ComException *after* the test suite finishes,
        /// or if you are unable to start the test because the VS test runner tells you 'Unable to start more than one local run'
        /// even if all tests seem to have finished</summary>
        /// <remarks>only to be used with xUnit STA worker threads</remarks>
        [AttributeUsage(AttributeTargets.Method)]
        public class DomainNeedsDispatcherCleanupAttribute : BeforeAfterTestAttribute
        {
            public override void After(MethodInfo methodUnderTest)
            {
                base.After(methodUnderTest);
    
                Dispatcher.CurrentDispatcher.InvokeShutdown();
            }
        }
    }
    

    哈哈哈.. 所以,如您所见,修复是微不足道的。我不记得了。当然,你只需要在你的拆解中InvokeShutdown 它应该被修复。

    【讨论】:

    • 太棒了!谢谢!这是 MSTest 简单的解决方案:[TestCleanup] public void Cleanup() { Dispatcher.CurrentDispatcher.InvokeShutdown(); }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2018-01-18
    • 2011-08-16
    • 2011-09-26
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多