none
RDPセッションを再接続した際に、BackgroundWorker の CancellationPending が true になる。 RRS feed

  • 質問

  • C#で BackgroundWorker を使ってファイルコピーを行うWPFアプリケーションを作っています。

    リモートデスクトップを使用し、このアプリケーションを実行し、サインアウトせずにセッションを閉じます。

    具体的には、リモートデスクトップ接続を「×」ボタンで閉じます。

    再度、リモートデスクトップ接続すると、セッションが再開されますが、その際に

    BackgroundWorker の CancellationPending が true になってしまい、スレッドが終了してしまいます。

    このような仕様なのでしょうか?

    2019年4月3日 4:54

回答

  • ご回答ありがとうございます。

    CancellationPending が true になる現象が発生する場合を確かめてみました。

    ユーザー切り替え時は、発生します。スクリーンロックは、発生しません。別のUACに昇格するアプリの起動は、発生しません。

    ログを出力させると、サインインの瞬間までは動いているようです。

    つまり、セッションが切れている間は動いているが、接続した瞬間に止まってしまう、という感じです。

    どうも、待ち時間が人が座って待っていられるくらいでないと、BackgroundWorker は使えないかなという印象です。

    今回は通常の Thread で対応します。

    • 回答としてマーク suzuken 2019年4月8日 5:23
    2019年4月5日 9:02
  • ご回答ありがとうございます。

    BackgroudWorkerのスレッドが終了してしまうことだけをみてCancellationPendingがTrueになったのだと考え違いをしていませんか?。

    いいえ、むしろ「CancellationPending が True になってしまうのはなぜなのか?」と疑問を感じて質問しました。

    後でわかりましたが、メインウィンドウだとこの現象が起き、Window.ShowDialog() で起動したサブウィンドウだとこの現象は起きませんでした。

    であれば WndProc などを調べてみれば何かわかるかもしれないのですが、今回は時間の都合上代替え処理で済ませました。

    皆様ありがとうございました。

    • 回答としてマーク suzuken 2019年4月8日 5:24
    2019年4月8日 5:10

すべての返信

  • 経験上、大多数のソフトウェアがリモートデスクトップ上で問題なく動作している現状を踏まえると、

    BackgroundWorker の CancellationPending が true になってしまい

    といった特異な現象が発生しているとは考えにくいです。

    別の要因を模索する方が現実的です。例えば、リモートデスクトップ上でなく、コンソール上で実行してもユーザー切り替えを行ったり、スクリーンロックしたり、別のUAC昇格するアプリケーションを起動したり、などでも同様の現象は発生しませんか?

    2019年4月3日 6:43
  • ご回答ありがとうございます。

    CancellationPending が true になる現象が発生する場合を確かめてみました。

    ユーザー切り替え時は、発生します。スクリーンロックは、発生しません。別のUACに昇格するアプリの起動は、発生しません。

    ログを出力させると、サインインの瞬間までは動いているようです。

    つまり、セッションが切れている間は動いているが、接続した瞬間に止まってしまう、という感じです。

    どうも、待ち時間が人が座って待っていられるくらいでないと、BackgroundWorker は使えないかなという印象です。

    今回は通常の Thread で対応します。

    • 回答としてマーク suzuken 2019年4月8日 5:23
    2019年4月5日 9:02
  • BackgroudWorkerのスレッドが終了してしまうことだけをみてCancellationPendingがTrueになったのだと考え違いをしていませんか?。

    BackgroundWorkerはDoWorkイベント内でエラーが発生したのにcatchしなかった場合、そのスレッドはCancellationPendingnがfalseでも終了します。
    たとえば、ファイルコピーをしているのであれば、ファイルアクセスなどでエラーが発生しているのに無視しているなどが考えられます。
    まずはエラーが発生していないかを調べる必要があるでしょう。

    namespace WindowsFormsApp1
    {
        using System;
        using System.ComponentModel;
        using System.Windows.Forms;
    
        public partial class Form1:Form
        {
            private BackgroundWorker backgroundWorker1;
            public Form1()
            {
                InitializeComponent();
    
                this.backgroundWorker1 = new BackgroundWorker()
                {
                    WorkerReportsProgress = true,
                    WorkerSupportsCancellation = true
                };
                this.backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
                this.backgroundWorker1.DoWork += backgroundWorker1_DoWork;
                this.backgroundWorker1.RunWorkerAsync();
            }
    
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                while(!this.backgroundWorker1.CancellationPending)
                {
                    System.Threading.Thread.Sleep(5000);
                    throw new ApplicationException();
                }
    
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if(e.Error != null)
                {
                    MessageBox.Show("Cancelled=" + e.Cancelled.ToString() + "\r\n\rnエラーが発生しました\r\n" + e.Error.Message);
                }
            }
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2019年4月5日 13:14
  • ご回答ありがとうございます。

    BackgroudWorkerのスレッドが終了してしまうことだけをみてCancellationPendingがTrueになったのだと考え違いをしていませんか?。

    いいえ、むしろ「CancellationPending が True になってしまうのはなぜなのか?」と疑問を感じて質問しました。

    後でわかりましたが、メインウィンドウだとこの現象が起き、Window.ShowDialog() で起動したサブウィンドウだとこの現象は起きませんでした。

    であれば WndProc などを調べてみれば何かわかるかもしれないのですが、今回は時間の都合上代替え処理で済ませました。

    皆様ありがとうございました。

    • 回答としてマーク suzuken 2019年4月8日 5:24
    2019年4月8日 5:10