2

アプリを.NET4に移行する一環として、WPF単体テストの一部をTeamCityで再び機能させるのに苦労しています。

どういうわけかWPFコントロール(たとえばListItem)を使用しているすべてのテストで、以前は取得しなかった例外が発生します。

System.InvalidOperationException: The calling thread must be STA, because many UI components require this.

私はそれが何を意味するのかを理解しています、そしてチェックした後、私のスレッドは確かにSTAではなくMTAであることがわかりました。

私の問題は、これを修正する方法と、この問題がどこから発生するのかがわからないことです...それはTeamCityの設定ですか?MSpec?繰り返しになりますが、.NET4に切り替える前は機能していました。

私は多くの異なる解決策を試しましたが、何もうまくいきませんでした。

また、(TeamCity + MSpec + WPFテストの特定のスタックで)これまで誰もこれを報告しなかったという事実にも少し戸惑っています。これは、どこかで非常に間違ったことをしていることを意味している可能性があります。

手がかりがあれば教えてください!

完全な例外:

System.InvalidOperationException: The calling thread must be STA, because many UI components require this.


 at System.Windows.Input.InputManager..ctor()
   at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
   at System.Windows.Input.KeyboardNavigation..ctor()
   at System.Windows.FrameworkElement.EnsureFrameworkServices()
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Control..ctor()
   at MyCompany.Dashboard.Client.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.ConfigureViewModel.CreateItem(String name) in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\MyCompany\Dashboard\Client\Plugins\Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModel.cs:line 171
   at MyCompany.Dashboard.Client.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.ConfigureViewModel.Initialise(Type type, IList`1 currentSelection, Action`1 selectionChangedCallback) in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\MyCompany\Dashboard\Client\Plugins\Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModel.cs:line 37
   at UnitTests.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.when_some_items_are_selected_on_the_chosen_list.<.ctor>b__1() in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\UnitTests.Plugins.Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModelTests.cs:line 82

この例外の場合、コードは単にListBoxItemをインスタンス化しようとしているだけで、特別なことは何もありませんが、MTAスレッドでそれを実行すると壊れます。

私が試したこと:

  • 現在のスレッドをSTAに設定する

    Thread.CurrentThread.SetApartmentState(ApartmentState.STA)

もちろん、スレッドが開始する前にのみ可能であるため、機能しません

  • STAとして初期化された別のスレッドでコードを実行します。MSpecの性質上、異なるメソッドが異なる時間に呼び出されるため、同じスレッドですべてを実行することはできないため、非常に複雑です。より正確には、「Becauseof」ステートメントと同じスレッドで「Establishcontext」を実行することはできません。

  • STAThread属性を使用します...はい、しかしどこですか?私が試したどこでも働いたことはありません

失敗したテストの例:

public class StaTestExample
{
    Establish context = () => _control = new ListBox();

    It should_not_be_null = () => _control.ShouldNotBeNull();

    protected static Control _control;
}
4

1 に答える 1

0

それは今動作します。

しかし問題は、それを説明できないことです。また、別のビルド サーバーでも失敗しますが、これについては気にしません。

誰かがその問題に遭遇した場合に備えて、ここで私たちがしたこと:

  • テスト カバレッジの無効化
  • MSPec タスクの無効化: ビルドは緑色になります
  • カバレッジと MSpec の再有効化: 動作します...

奇妙なことは、正確なプロセスが別のビルド サーバー (もう使用していない古いサーバー) に適用され、それでも失敗することです。

変更されたと考えることができるものは他にありません。

だから、ちょっと謎です... 私たちを噛むために戻ってこないことを願っています!

于 2013-03-13T11:49:49.610 に答える