

WPF で WinRT の PdfDocument
を使用したいのですが、アプリを終了してもプロセスが残ってしまう場合があります。何か足りない処理があるのでしょうか。

以下が再現コードになります。

  * PdfPage.RenderToStreamAsync() を実行するとプロセスが残ってしまいます。
  * VisualStudio2022 でのデバッグ実行では問題は発生しません。「デバッグなしで開始」すると再現します。
  * GC.Collect() はこの現象の再現率を 100% 近くに高めます。現象との関連は不明です。
  * Windows10-64bit, .NET6, WPF の環境です。TargetFramework は net6.0-windows10.0.17763.0 です。

[code]

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Loaded += MainWindow_Loaded;
            }
    
            private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                await GetPdfPageStream(@"sample.pdf", 0);
                GC.Collect();
                this.Close();
            }
    
            private static async Task<MemoryStream> GetPdfPageStream(string path, uint index)
            {
                using var pdfStream = File.OpenRead(path);
                using var winrtStream = pdfStream.AsRandomAccessStream();
                var pdfDocument = await PdfDocument.LoadFromStreamAsync(winrtStream);
                using var pdfPage = pdfDocument.GetPage((uint)index);
                var ms = new MemoryStream();
                var outStream = ms.AsRandomAccessStream();
                await pdfPage.RenderToStreamAsync(outStream);
                ms.Seek(0, SeekOrigin.Begin);
                return ms;
            }
        }
    
[/code]


CC BY-SA 4.0
2022-08-23T05:57:29.523
90712
2022-10-20T02:44:47.087
14817
question
.net wpf
PdfDocument使用後にアプリ終了するとプロセスが残ってしまう


同じ問題をかかえていました。  
なぜプロセスが残ってゾンビ化するのかはわかりませんが、プロセスを残さない方法としては、標準の×ボタンを無効化し、ほかのボタンやメニューから終了させるとプロセスを残さず終了することが可能です。スマートな解決案ではありませんが試してみるとよいと思います

## 終了ボタンにイベント追加(xaml)

[code]

    <Window x:Class=""
            xmlns=""...
            Closin="window_closing" <!-- 追記 --> ...>
    
[/code]

## 終了イベントのキャンセル

[code]

    private void window_closing(object sender, System.ComponentModel.CancelEventArgs e) {
        MessageBox.Show("メニューから終了してください..."); //　任意の処理
        e.Cancel = true;
    }
    
[/code]

以上で標準の×ボタンを無効化できます。  
他の閉じる方法として、バッチを作成して何かしらのイベントが発生したタイミングでバッチを実行する方法をとりました。(Taskkillを使用してアプリケーションを終了させるとプロセスが残らないことを確認しました。)

## close.batの作成

[code]

    @echo off
    taskkill /F /IM ファイル名.exe
    
[/code]

## イベント作成

[code]

    private void onClickClose(object sender, RoutedEventArgs e) {
        Process process = new Process();
        process.StartInfo.FileName = "close.bat";
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.UseShellExecute = false;
        process.Start()
    }
    
[/code]

これでプロセスのゾンビ化を防ぐことはできます。


CC BY-SA 4.0
2022-08-23T23:33:19.553
90727
2022-08-23T23:33:19.553
54133
90712
answer


現象が発生するPCがないため、解決できるかわかりませんが、以下のように Shutdown() を非同期で呼び出して解決できませんか。

[code]

    protected override void OnClosed(EventArgs e)
    {
        var app = Application.Current;
        Dispatcher.BeginInvoke(new Action(() => app.Shutdown()));
        base.OnClosed(e);
    }
    
[/code]


CC BY-SA 4.0
2022-10-20T02:44:47.087
91687
2022-10-20T02:44:47.087
54922
90712
answer