Process.Start导致我的WPF程序崩溃

时间:2014-10-24 01:55:41

标签: c# wpf memory-leaks

我有一个WPF程序,它在一个进程中打开一个Word文档,并在继续之前等待该进程完成。如果我让Word打开几个小时,程序就会崩溃。

我可以看到我的应用程序的内存在进程运行时稳步增加。

我尝试了两种方法来执行此操作,两者都有相同的内存问题。

方式#1

public void ShowExternalReference(string externalRef, bool waitForCompletion)
{
    if (!string.IsNullOrEmpty(externalRef))
    {
        using (var p = Process.Start(@externalRef))
        {
            if (waitForCompletion)
            {
                // Wait for the window to finish loading.
                p.WaitForInputIdle();

                // Wait for the process to end.
                p.WaitForExit();
            }
        }
    }
}
方式#2

public void ShowExternalReference(string externalRef, bool waitForCompletion)
{
    if (!string.IsNullOrEmpty(externalRef))
    {
        using (var p = Process.Start(@externalRef))
        {
            if (waitForCompletion)
            {
                while (!p.HasExited)
                {
                    Thread.Sleep(1000);
                }
            }
        }
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我已经阅读了评论,很长一段时间WaitForExit()似乎是一个记忆问题。

所以我会做那样的事情:

  1. 启动流程并仅检索其PID
  2. 定期检查流程是否仍处于活动状态
  3. 也许这不会产生相同的内存问题。

    我的建议:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
    
        private System.Threading.Timer _timer;
    
        public MainWindow()
        {
            InitializeComponent();
    
            this.Content = new TextBlock() { Text = "Close notepad.exe when you want..." };
    
            // - Launch process
            Process p = Process.Start("notepad.exe");
            int processId = p.Id;
            _timer = new System.Threading.Timer(new System.Threading.TimerCallback(o => CheckPID((int)o)), processId, 0, 1000);
        }
    
        /// <summary>
        /// Check if Process has exited
        /// </summary>
        /// <remarks>This code is NOT in UI Thread</remarks>
        /// <param name="processId">Process unique ID</param>
        private void CheckPID(int processId)
        {
            bool stillExists = false;
            //Process p = Process.GetProcessById(processId); // - Raises an ArgumentException if process has alredy exited
            Process p = Process.GetProcesses().FirstOrDefault(ps => ps.Id == processId);
            if (p != null)
            {
                if (!p.HasExited)
                    stillExists = true;
            }
    
            // - If process has exited, do remaining work and stop timer
            if (!stillExists)
            {
                _timer.Dispose();
    
                // - Ask UI thread to execute the final method
                Dispatcher.BeginInvoke(new Action(ExternalProcessEnd), null);
            }
        }
    
    
        /// <summary>
        /// The external process is terminated
        /// </summary>
        /// <remarks>Executed in UI Thread</remarks>
        private void ExternalProcessEnd()
        {
            MessageBox.Show("Process has ended");
        }
    
    }
    

    缺点是我们无法检索StandardOutput,StandardError和ExitStatus。