18

私の一般的なセットアップ: 私たちは小さな GUI を備えた小さな Excel インポーターを作成しました。基礎となるフレームワークは TestStack.White です。Excel ファイルと他のいくつかのユーザー対話をインポートした後、テストは System.ComponentModel.BackgroundWorker 内で開始されます。これは、膨大な数の子要素を含む要素を見たり、対話したりしない限り、正常に動作します。

しかし、多くの要素を持つ TestStack.White.UIItems.WindowItems.Window または TestStack.White.UIItems.UIItemContainer と対話するとすぐに、testexecution は終了します。

対話とは、null でないチェックやローカル変数への代入などの単純なものから、子の数を要求するようなものまですべてを意味します。テスト実行を終了するいくつかの例: 1)

if(theElement != null){ //everything after this line does not happen. The operator doesn't seem to be overloaded
   doStuff(); //it never reaches this point
}

2)

UIItemContainer pointOfInterest = theElement; //everything after this line does not happen

3)

System.Diagnostics.Debug.WriteLine("AmountOfElements: " + UIAnchor.Items.Count); //the output doesn't come. everything after this line does not happen

何百もの要素を持たないウィンドウでは、3 つの例はすべて意図したとおりに機能します。

多くの要素とは、たとえば、ScrollView を内部に持ち、数十または数百のエントリを持つテーブルを持ち、すべてのエントリがテキストまたはチェックボックスなどを含む 3 ~ 4 列で構成されるウィンドウを意味します。

Backgroundworkers RunWorkerCompleted と Disposed は呼び出されません。意図的に配置された try/catch ブロックを使用しても、例外はまったく発生しません。デバッガーは問題の原因となっている行に到達し、それだけです。1時間待っても、その後何も来ません。

代わりに、「スレッド {some hex id} はコード 259 (0x103) で終了しました」といういくつかの異なるメッセージが表示されます。Visual Studio の出力ウィンドウで。これは私の最後のテスト実行からのものです:

The thread 0x830 has exited with code 259 (0x103).
The thread 0xfc0 has exited with code 259 (0x103).
The thread 0xc04 has exited with code 259 (0x103).

私がこのメッセージを理解している限り、それはスレッドがまだ生きていることを意味します。https://stackoverflow.com/a/22395548/1171328

エラーの原因となった要素の内容を確認するためにデバッガーにアクセスすると、Items (子要素を持つ List) の後に続くすべての要素 (Items を含む) でタイムアウトが発生します。

また、問題は、このスレッドの場合のように、メイン スレッドが終了することではありません (または終了すべきではありませんか? )

ここで何が起こっているのか、またはこの問題を解決する方法を知っている人はいますか?

これは私がアプリを起動する方法です:

Application app = TestStack.White.Application.Launch(pathToExeFile);
context.setApp(app); //context is a class with static variables to eas the access to all kind of stuff, so that i access it without having 20 parameters in every method (e.g. Button.Click())

その後、ユーザーはテストするウィンドウを設定します (モーダル ウィンドウである場合とそうでない場合がありますが、何百もの要素を持たないウィンドウでは機能します)。

foreach (Window win in context.getApp().GetWindows()) {
      System.Diagnostics.Debug.WriteLine("###SelectWindow: " + win.Name + " # " + win.PrimaryIdentification + " # " + win.Title);

      if (win.Name.Equals(nameOfWindowToTest)) {
        System.Diagnostics.Debug.WriteLine("###SelectWindow: gefunden");
        context.UIAnchor = win;
        System.Diagnostics.Debug.WriteLine("####SelectWindow: Anz Items: " + context.UIAnchor.Items.Count); //this gets called, but is the very last thing the thread does
        return null; //does not happen
      }
    }

context.UIAnchor は上記の要素です。その後、ユーザーが設定したメソッド (Button.Click など) が呼び出されます。おかしなことに、context.UIAnchor = win と items.count の出力が機能します。

更新: テスト対象のアプリを閉じると、テスト プログラムを閉じる前に、ElementNotAvaiableException が発生します。したがって、スレッドが完全に死んでいるわけではありません。

4

2 に答える 2

5

上記の私のコメントをフォローアップすると、おそらくこのBug / Featureが原因で、 BackgroundWorker が表示されない例外をスローすると思います。

この小さなスニペットを実行すると、デバッグ/例外ダイアログで「スロー」をマークするまで、未処理の例外は表示されません。

Public Class Form1

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        For I As Integer = 0 To 100
            BackgroundWorker1.ReportProgress(I)
            Threading.Thread.Sleep(25)
            If I = 50 Then Throw (New NullReferenceException)
        Next
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ProgressBar1.Value = 0
    End Sub
End Class

(VB には申し訳ありませんが、すべての CLR に適用する必要があります)

このサンプルは、(ボタンをクリックした後) 50% まで満たされてから停止する ProgessBar を示しています。BackgroundWorker は実行されておらず、Done イベントもありません。スローにステップインすると、単にメソッドが終了します。

編集: 私の最初のサンプルは RunWorkerCompleted イベントを見逃していました。現在発火中です。そのため、これはあなたの質問とはまったく関係がないかもしれません。申し訳ありません。

于 2015-04-29T11:34:32.733 に答える
1

app.config で従来の例外処理モードに切り替えるとどうなりますか?

<configuration>
  <runtime>
    <legacyUnhandledExceptionPolicy enabled="1"/>
  </runtime>
</configuration>
于 2015-05-01T05:35:47.003 に答える