线程开始导致OOM异常

时间:2014-11-13 12:29:26

标签: c# multithreading out-of-memory prism

Thread splashScreenThread = new Thread(new ParameterizedThreadStart(DisplaySplashScreen));
splashScreenThread.SetApartmentState(ApartmentState.STA);
splashScreenThread.IsBackground = true;
splashScreenThread.Start(moduleName);

上述代码执行30到50次崩溃后出现OutOfMemoryException。

如果我在DisplaySplashScreen函数关闭时尝试使用splashScreenThread.Join,则应用程序会挂起。

更新:

开发机器是64位机器,所讨论的应用程序是使用PRISM的32位WPF应用程序。

每次打开模块时都会显示启动窗口。模块打开后,关闭启动窗口。

private void DisplaySplashScreen(object moduleName)
        {
            if (moduleName != null)
                splashScreen = new SplashWindow(moduleName.ToString(), this.SplashScreenDescription);
            else
                splashScreen = new SplashWindow(string.Empty, string.Empty);

            splashScreen.ShowDialog();
        }

注意:SplashWindows是自定义窗口,稍后会自动显示和关闭。

模块加载开始和加载结束fns:

private void ModuleLoadingStart(object moduleName)
        {
            if (this.ModuleLoadingVisibility != Visibility.Visible)
            {
                this.ModuleLoadingVisibility = Visibility.Visible;

                // Spawn off a new thread
                Thread splashScreenThread = new Thread(new ParameterizedThreadStart(DisplaySplashScreen));
                splashScreenThread.SetApartmentState(ApartmentState.STA);
                splashScreenThread.IsBackground = true;
                splashScreenThread.Start();
            }
        }



private void ModuleLoadingEnd()
        {
            if (this.ModuleLoadingVisibility != Visibility.Collapsed)
            {
                this.ModuleLoadingVisibility = Visibility.Collapsed;

                while (true)
                {
                    if (splashScreen == null)
                        Thread.Sleep(100);
                    else
                        break;
                }

                CloseSplashScreenDelegate myDel = new CloseSplashScreenDelegate(splashScreen.Close);

                splashScreen.Dispatcher.Invoke(myDel, null);
            }
        }

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

WTF你实例化了这么多线程吗?!你知道Thread是饥饿的野兽吗?每一个都占用了数兆字节的连续内存!

反正。你说那个

  

如果我在DisplaySplashScreen函数关闭时尝试使用splashScreenThread.Join,则应用程序会挂起。

这很容易诊断。这里的问题是你Thread.Join完全错了。

Thread.Join的目的是阻止(停止一切并等待)当前线程,直到另一个Thread上的工作完成。这里的问题是splashScreenThread处于循环中。专门循环显示代码。所以它永远不会完成。因此,你告诉你的主线程要等到永远不做任何事情。