在另一个线程中创建窗口后WPF内存泄漏

时间:2010-10-30 14:55:08

标签: wpf memory-leaks thread-safety

我正在另一个线程中创建窗口。关闭线程后,某些资源窗口不会从内存中释放。因为Windows任务管理器中的这个增长计数器GDI对象和用户对象。未发布的图形是字体和区域。我不知道发生了什么......

public class WaitingWindowManager
{
    private Thread thread;
    private bool canAbortThread = false;
    private Window waitingWindow;

    public void BeginWaiting()
    {
        this.thread = new Thread(this.RunThread);
        this.thread.IsBackground = true;
        this.thread.SetApartmentState(ApartmentState.STA);
        this.thread.Start();
    }

    public void EndWaiting()
    {
        if (this.waitingWindow != null)
        {
            this.waitingWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { this.waitingWindow.Close(); }));
            while (!this.canAbortThread) { };
        }

        this.thread.Abort(); 
    }

    public void RunThread()
    {
        this.waitingWindow = new Window();
        this.waitingWindow.Closed += new EventHandler(waitingWindow_Closed);
        this.waitingWindow.ShowDialog();
    }

    void waitingWindow_Closed(object sender, EventArgs e)
    {
        this.canAbortThread = true;
    }
}

并致电:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();  
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
            WaitingWindowManager waitingWindowManager = new WaitingWindowManager();
            waitingWindowManager.BeginWaiting();
            Application.Current.Dispatcher.Thread.Join(5000);
            waitingWindowManager.EndWaiting();
    }
}

2 个答案:

答案 0 :(得分:2)

在waitingWindow_Closed事件中删除已关闭的事件处理程序。它导致你的窗户不被处理。如果手动添加事件,则需要确保在完成后删除它们。

我还注意到与wpf中的内存泄漏有关的另一个Stackoverflow question。它引用了这个article也许这会对你有帮助。

答案 1 :(得分:0)

在结账代码中添加Dispatcher.CurrentDispatcher.InvokeShutdown();。这应该照顾任何泄漏的记忆。