2010-10-30 26 views
1

我在另一个线程中创建窗口。关闭线程后,某些资源窗口不会从内存中释放。由于Windows任务管理器中增加了计数器GDI对象和用户对象。没有发布的图形是字体和区域。我没有想法是怎么回事...在另一个线程中创建窗口后WPF内存泄漏

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

在您的waitingWindow_Closed事件中移除您的Closed event handler。它导致你的窗户不被处置。如果您手动添加事件,则需要确保在完成后将其删除。

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

+0

不起作用。在这种情况下,我也有泄漏记忆。 public void RunThread() Window waitingWindow = new Window(); // waitingWindow.Closed + = new EventHandler(waitingWindow_Closed); waitingWindow.ShowDialog(); } – LuckyDan 2010-10-30 19:32:45

+0

我所做的是这样的。我使用了Femaref的建议并删除了处理程序。我确实允许新窗口被丢弃。 void waitingWindow_Closed(object sender,EventArgs e) { this.waitingWindow.Closed - = new EventHandler(waitingWindow_Closed); Dispatcher.CurrentDispatcher.InvokeShutdown(); this.canAbortThread = true; }如果这仍在泄漏什么物体正在泄漏 – 2010-10-30 20:12:07

+0

我无法理解。假设事件处理程序阻止我们处理对象。 如果我添加 空隙waitingWindow_Closed(对象发件人,EventArgs的) { \t this.waitingWindow.Closed - =新的EventHandler(waitingWindow_Closed); \t this.canAbortThread = true; } 它必须解决问题。但这不起作用。 此外,如果你没有一般的处理程序,结果是相同的:内存泄漏 – LuckyDan 2010-10-30 20:29:22

0

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

+0

这是WPF不是Windows窗体在第一次和第二我没有创建 gdi ojects – LuckyDan 2010-10-30 15:07:27

+0

这不是工作。窗口(waitingWindow)被销毁,在内存分析器中可以看到 ,但WaitingWindowManager类的对象不能销毁。而这种行为只有在线程中创建WPF窗口后出现 – LuckyDan 2010-10-30 18:08:22