Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ShellWindows和OutOfMemoryException?_C#_Memory Leaks_Out Of Memory - Fatal编程技术网

C# ShellWindows和OutOfMemoryException?

C# ShellWindows和OutOfMemoryException?,c#,memory-leaks,out-of-memory,C#,Memory Leaks,Out Of Memory,我有一个在Internet Explorer中打开URL的方法。如果已打开internet explorer,则应在新选项卡中打开它。如果没有,它应该打开一个新的internet explorer 我的代码: public static void OpenURL(string Url) { bool already_navigated = false; ShellWindows instances = new ShellWindows();

我有一个在Internet Explorer中打开URL的方法。如果已打开internet explorer,则应在新选项卡中打开它。如果没有,它应该打开一个新的internet explorer

我的代码:

    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();
        /*
        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }*/
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;
        /*
        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }*/
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
这太棒了!但是当我调用这段代码时,我的内存在无限循环中增加,直到我得到一个OutOfMemoryException

经过一些尝试和错误,我发现这段代码抛出了一个异常:

    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();
        /*
        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }*/
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;
        /*
        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }*/
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
而此代码没有:

    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;

        ShellWindows instances = new ShellWindows();
        /*
        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }*/
    }
    public static void OpenURL(string Url)
    {
        bool already_navigated = false;
        /*
        ShellWindows instances = new ShellWindows();

        //Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            foreach (InternetExplorer ie in instances)
            {
                if (ie.Name == "Windows Internet Explorer")
                {
                    if (!already_navigated)
                    {
                        //Navigate and open in New Tab
                        already_navigated = true;
                        ie.Navigate(Url, 0x10000);

                        //Bring window to front
                        IntPtr hwnd = (IntPtr)ie.HWND;
                        WindowHandler.Window w = new WindowHandler.Window(hwnd, "Internet Explorer");
                        w.Minimize();
                        w.Restore();
                    }
                }
            }
        }*/
        //No internet explorer found!
        if (!already_navigated)
        {
            //Start new Internet Explorer
            Process proc = Process.Start("IExplore.exe", Url);
        }
    }
这只给我留下了一个结论,问题在于:

 ShellWindows instances = new ShellWindows();
但在谷歌搜索之后,我找不到有类似问题的人。所以我不确定我是否做错了什么,或者我在这个问题上是否是对的


有人知道发生了什么吗?

此代码应该适用于您:

public static void OpenURL(string Url)
{
    var t = Type.GetTypeFromProgID("Shell.Application");
    dynamic o = Activator.CreateInstance(t);
    try
    {
        var instances = o.Windows();

        // Check if there is an Internet Explorer
        if (instances.Count > 0)
        {
            for (int i = 0; i < instances.Count; i++)
            {
                var ie = instances.Item(i);
                if (ie == null) continue;

                var path = System.IO.Path.GetFileName((string)ie.FullName);
                if (path.ToLower() == "iexplore.exe")
                {
                    //Navigate and open in New Tab
                    ie.Navigate(Url, 0x10000);
                    return;
                }
            }
        }
    }
    finally
    {
        Marshal.FinalReleaseComObject(o);
    }

    //No internet explorer found. Start a new onr
    Process.Start("IExplore.exe", Url);
}
publicstaticvoidopenurl(字符串Url)
{
var t=Type.GetTypeFromProgID(“Shell.Application”);
动态o=Activator.CreateInstance(t);
尝试
{
var实例=o.Windows();
//检查是否有Internet Explorer
如果(instances.Count>0)
{
for(int i=0;i
ShellWindows是一个COM对象。您依赖垃圾收集器来释放RCWs(运行时可调用包装器),并由其终结器处理

但是,当您的代码只调用OpenUrl()而不做其他任何事情时,这将无法很好地工作。垃圾收集器仅在分配托管对象时运行。如果您不这样做,并且您发布的代码没有做很多这方面的工作,那么您将面临耗尽非托管内存(COM对象使用的那种内存)的巨大风险

这种情况很容易诊断,请使用Perfmon.exe并查看.NET CLR内存的性能计数器。“Gen 0 Collections”计数器显示执行Gen 0垃圾收集的频率。如果该计数器在代码运行时没有经常更改,则很可能出现OOM kaboom

这就是GC.Collect()存在的原因,计算您创建的“ie”实例的数量,并以某种神奇的数字调用Collect。Marshal.ReleaseComObject()也有帮助,通常会带来更多的麻烦,但在这里应该可以轻松操作。在你的循环中使用break

ShellWindows的另一个方面是它是一个单元线程COM对象。一个昂贵的词,意味着它不是线程安全的。这在COM中很重要,它代表对象负责线程安全。如果此代码不在Winforms或WPF应用程序的主线程上运行,您很可能会遇到麻烦。像控制台模式的应用程序或服务。或者,如果您在工作线程上运行此代码


对于公寓线程COM对象来说,这不是一个愉快的家,它需要一个STA线程来满足线程安全要求。COM将处理这个问题,它将创建一个新线程来给对象一个安全的家。当您创建了许多寿命过长的对象时,这可能会失控。也很容易诊断,打开非托管调试并关注“调试+窗口+线程”窗口。我们不知道您的代码的其余部分在做什么,但是当代码运行一段时间后,看到数百个线程就意味着厄运。每个线程为其堆栈占用一兆字节的虚拟内存,消耗32位进程所需的时间不超过几千。通过在Main()方法上应用[STAThread]属性,或者在启动线程之前对线程调用SetApartmentState()来修复此问题。

我打赌这是内存泄漏。在C#中听起来很奇怪,但是是的,你为什么不在不同的点上打破它,看看哪一个喜欢增加了内存的使用@AnnArbor87我无法真正调试,因为目前我无法在我用来开发的机器上测试代码。我只能通过更改代码和记录发生的情况来进行调试。尝试注释掉代码的其他部分,如内部IF(!ready_navigated)并发布发生的情况,我认为您遇到的问题是因为IE对象。你会关闭Instance吗?你想实现什么?那没什么区别。只有当我删除ShellWindows行时,它才不会导致内存泄漏。当我尝试执行你的代码时,我出现了两个错误。第一个声明指出,为了使用“using”shell,Windows必须可转换为System.IDisposable。第二个错误是,我无法将[]索引应用于ShellWindows的表达式。我很好奇在应用程序每次运行期间调用OpenURL()的次数和次数?您的应用程序是控制台应用程序、Windows(UI桌面)还是什么?请尝试使用删除第一个应用程序,保留foreach,但应用其余建议。请尝试我刚才添加的代码。它在我的机器上工作,正如你所期望的。在它开始变大之前,我只叫它一次。我只使用.NET4.0,但我发现你的答案非常有用。谢谢你,我成功了!我所做的是在OpenURL中创建一个新线程,启动它并在STA中加入它。这似乎处理得很好!