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

C# Process.Start导致我的WPF程序崩溃,c#,wpf,memory-leaks,C#,Wpf,Memory Leaks,我有一个WPF程序,它在进程中打开Word文档并等待进程完成后再继续。如果我让Word打开几个小时,我的程序就会崩溃 在进程运行时,我可以看到我的应用程序的内存稳步增加 我尝试了两种方法,但都有相同的内存问题 路#1 路#2 有什么想法吗?我读过评论,很长一段时间以来,WaitForExit()似乎存在内存问题 所以我会这样做: 启动进程并仅检索其PID 定期检查流程是否仍处于活动状态 也许这不会产生同样的内存问题 我的建议: /// <summary> /// Interactio

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

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

我尝试了两种方法,但都有相同的内存问题

路#1

路#2


有什么想法吗?

我读过评论,很长一段时间以来,
WaitForExit()似乎存在内存问题

所以我会这样做:

  • 启动进程并仅检索其PID
  • 定期检查流程是否仍处于活动状态
  • 也许这不会产生同样的内存问题

    我的建议:

    /// <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");
        }
    
    }
    
    //
    ///MainWindow.xaml的交互逻辑
    /// 
    公共部分类主窗口:窗口
    {
    专用系统.Threading.Timer\u Timer;
    公共主窗口()
    {
    初始化组件();
    this.Content=new TextBlock(){Text=“需要时关闭notepad.exe…”;
    //-启动过程
    进程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);
    }
    /// 
    ///检查进程是否已退出
    /// 
    ///此代码不在UI线程中
    ///进程唯一ID
    私有无效检查PID(int processId)
    {
    bool-stillExists=false;
    //Process p=Process.GetProcessById(processId);//-如果进程已退出,则引发ArgumentException
    进程p=Process.GetProcesses().FirstOrDefault(ps=>ps.Id==processId);
    如果(p!=null)
    {
    如果(!p.HasExited)
    stillExists=真;
    }
    //-如果进程已退出,则执行剩余工作并停止计时器
    如果(!仍然存在)
    {
    _timer.Dispose();
    //-要求UI线程执行最终方法
    Dispatcher.BeginInvoke(新操作(ExternalProcessEnd),null);
    }
    }
    /// 
    ///外部进程被终止
    /// 
    ///在UI线程中执行
    私有void ExternalProcessEnd()
    {
    MessageBox.Show(“进程已结束”);
    }
    }
    

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

    您在哪个线程中调用它?你没有阻塞WPF的调度程序线程,是吗?无法重新编程。此外,这也是不可靠的,如果用户打开其他Word文档,则在关闭所有文档之前,流程不会退出。你认为吗?正如你提到的,内存不断增加,所以这肯定是一个内存泄漏和崩溃的情况,因为像OOM之类的东西,请检查我的一个与调试OOM有关的响应:如果你的应用程序闲置而不启动和等待Word实例,你的应用程序是否会耗尽内存?
    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);
                    }
                }
            }
        }
    }
    
    /// <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");
        }
    
    }