开发者

COM exceptions on exit with WPF

After execution both of the following test cases, a COM execution is printed to the console. What am I doing wrong?

If I run either test singly, or if I run both tests together, the exception is written to the console exactly once. This makes me suspect that there's some sort of a per-AppDomain resource that I'm not cleaning up.

I have tried the tests with NUnit and with MSTest, with the same behavior in both environments. (Actually, I'm not sure if running both tests in MSTest results in a single exception printout or two.)

Exception:

System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
at System.Windows.Input.TextServicesContext.StopTransitoryExtension()
at System.Windows.Input.TextServicesContext.Uninitialize(Boolean appDomainShutdown)
at System.Windows.Input.TextServicesContext.TextServicesContextShutDownListener.OnShutDown(Object target)
at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e)

Test code:

using NUnit.Framework;

namespace TaskdockSidebarTests.Client
{
    [TestFixture, RequiresSTA]
    public class ElementHostRCWError
    {
        [Test]
        public void WinForms()
        {
            var form = new System.Windows.Forms.Form();
            var elementHost = new System.Windows.Forms.Integration.ElementHost();
            form.Controls.Add(elementHost);

            // If the form is not shown, the exception is not printed.
            form.Show();

            // These lines are optional. The exception is prin开发者_JAVA百科ted with or without
            form.Close();
            form.Controls.Remove(elementHost);
            elementHost.Dispose();
            form.Dispose();
        }

        [Test]
        public void WPF()
        {
            var window = new Window();

            // If the window is not shown, the exception is not printed.
            window.Show();

            window.Close();
        }
    }
}


Looking at my own code again, the following line might help for the WPF test, right at the end.

Dispatcher.CurrentDispatcher.InvokeShutdown();


You probably can't unit test the Window and Form classes at all. Both WinForms applications and WPF applications have an Application class used to start the underlying plumbing (message pumps and whatnot). I bet it's the key to avoiding that exception.

You're not doing that there and may not be able to.

Every recommendation for unit testing I've ever read is that you refactor so that the Form classes and Window classes don't do anything you need to unit test (like the M-V-VM pattern in WPF). Could have something to do with not being able to show the UI.

There are other ways to test a UI. This answer discusses unit testing UI.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜