私のアプリでこれらの未処理の例外が表示されます。 ObservableCollectionsのObservableCollectionにバインドされたグループ化されたListViewでリーフアイテムを追加および削除するときに発生すると思います。
役立つ場合に備えて、コンパイルされたバインディングを使用しています。
System.InvalidOperationException: Operation is not valid due to the current state of the object.
これは、AppCenterに表示されるスタックトレースです。
TypedBinding`2[TSource,TProperty].Apply (System.Boolean fromTarget)
TypedBinding`2+PropertyChangedProxy[TSource,TProperty].<OnPropertyChanged>b__16_0 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.39(intptr,intptr)
申し訳ありませんが、まだしっかりとした再現はありません。
@mfeingolこれを絞り込むことができる場合は、この問題を示す小さなプロジェクトを添付していただけますか? ありがとう!
今週末はそうしようと思いますが、これはオンデマンドで再現するのはちょっと難しいです。 コードの理解に基づいて、あなたの側から何か手がかりはありますか?
これは、DataTypeを使用したXAMLバインディングに関連しているようです。
私は今旅行中ですが、一時的な回避策はコンパイルされたバインディングを無効にすることでした。
@mfeingolわかりました、それは正しいと思います。 機会があれば、問題を絞り込むためのサンプルプロジェクトを提供してください。 ありがとう!
iOSとAndroidの両方で同じ問題が発生しています。 コンパイルされたバインディングを使用していません。
AppCenterの問題:
TypedBinding 2[TSource,TProperty].Apply (System.Boolean fromTarget)
TypedBinding
2 + PropertyChangedProxy [TSource、TProperty]。
Thread + RunnableImplementor.Run()
IRunnableInvoker.n_Run(System.IntPtr jnienv、System.IntPtr native__this)
(ラッパー動的メソッド)System.Object.26(intptr、intptr)
Xamarinフォームプロジェクト、ViewModelを含むXamlページ-ScrollViewを含むグリッド-ScrollViewにはラベルが含まれます。 ものすごく単純。
@samhouts :最善を尽くしましたが、サンプルアプリで問題を再現できません。 ただし、本番アプリには100%の再現があります。
チームの誰かにAzureDevOpsプロジェクトへのアクセス許可を与えて、問題を再現できるようにすることはできますか?
microsoft.comのshneuvil
現在の場所: https :
再現手順:
git checkout 6698-repro
とビルド。 パッケージを取得するには、NuGetディレクトリのリストに外部ディレクトリを追加する必要がある場合があります。何らかの理由でこのような単純な旅行で再現できない場合は、より多くの場所でより洗練された旅行をエクスポートします。
@PureWeen :これがうまくいかない場合はお知らせください。
@mtirona :先ほどコメントを逃しました、ごめんなさい。 コンパイルされたバインディングを使用せずにこれが表示されるのは奇妙なことです。 オンデマンドでクラッシュをトリガーする単純な再現プロジェクトがあるとは思いませんか?
@mfeingolこの問題は、アプリケーション内でランダムに発生しています。 オンデマンドで簡単に再作成することはできません。AppCenterで何百ものクラッシュが発生し、問題が文書化されています。 問題を防ぐ方法についての指示をいただければ幸いです...
@mtirona :XAMLのどこでもx:DataTypeを使用していないことを100%確信していますか?
@mfeingol親ページにx:DataTypeがあったので、アプリケーション全体を
独自のコードでTypedBindingsを作成しない限り、これがXamlCに関連していることは確かです(Xamlコンパイラーによってのみ作成されます)
補足:Xamarin Forms 3.6を使用していて、最新の4.1に更新しました。 アプリを最初に実行すると、グループ化されたリストビューページにアイテムをすばやく追加しているときに、すぐにこのクラッシュが発生しました。 したがって、この問題は4.1.0.618606でも引き続き発生します。
@PureWeen :上記の再現手順を更新して、問題をすぐに再現する必要があるチェックアウト可能なブランチを参照するようにしました。
@mfeingolあなたは私のためにこれをすることができますか?
何らかの理由でこのような単純な旅行で再現できない場合は、より多くの場所でより洗練された旅行をエクスポートします。
私はあなたのステップを試しましたが、何もクラッシュしませんでした
了解しました。@ mfeingolこの問題を引き起こすためにデータがどのように、またはなぜ
TypedBindingsはBindableObjectへのWeakReferenceを使用するため、それがBindableObjectを参照する唯一のものである場合、その参照は失われます。
クラッシュするコードは次のとおりです
`` `C#
if(!_ weakTarget.TryGetTarget(out target))
新しいInvalidOperationException();をスローします。
If you look at the output of the application while it's running the exception always happens after a GC which makes sense why you are only seeing this after loading a larger data set.
As a test with the TypeBindings I created a nuget where it stores the source and target to a local variable just to see what would happen
```C#
_weakSource.SetTarget(source);
_weakTarget.SetTarget(bindObj);
_bindObj = bindObj;
_source = source;
ApplyCore(source, bindObj, targetProperty);
}
BindableObject _bindObj;
object _source;
そして、私がそうすれば、クラッシュは起こりません。
私の考えでは、ViewCellにバインドされているLocationDayWeatherViewModelのインスタンスを参照しているのは、TypeBindingだけである場所に、どういうわけかデータが到達していると思います。 これがどういうわけか私たちとあなたの側の例外であるかどうか、私はまだ完全に追跡していません。 ListViewにバインドされている作成済みのすべてのLocationDayWeatherViewModelへの参照を維持していることを確認できますか?
これを調べてくれてありがとう! この問題はアプリ全体の外で再現するのはかなり難しいので、弱い参照を伴うものになることは理にかなっています。 より単純な再現にメモリプレッシャーを追加すると、同じ問題が発生する可能性があるのではないかと思います。
とにかく、 LocationDayWeatherViewModel
インスタンスがビューモデルによって参照されないのは、天気の日の更新中だけです。この場合、コードは、新しいアイテムを挿入する前に、バインドされたObservableCollectionのアイテムをクリアします。 これは、bpsを設定する場合に備えて、 ExpandableGroupCollectionViewModel.Refresh
奥深くで発生します。
ただし、バインドされたObservableCollectionをクリアすることは安全な操作であるはずであり、XFバインディングが弱い参照を使用する理由は私にはわかりません。 それはまさにこの種のレースがあるように聞こえます。
余談ですが、 Refresh
でクリアする前に、 this
のアイテムを一時リストにコピーしようとしましたが、驚くべきことに、それは問題を回避していないようです。 メソッドの最後にあるリストを参照して、GCがリストを削除しないようにしました。 XFが古いバインディングを「後で」使用しようとしている場合、これは理にかなっていると思います。アプリがバインドされた参照を安定させる良い方法がないことを示唆しています。 しかし、私は物事を誤解しているかもしれません。
(はい、天気/エキスパンダーのコードは少し制御不能です。XFにネイティブのエキスパンダーコントロールがあればいいのにと思います...)
メモリプレッシャーを追加するか、
だからはっきりと私は何が起こっているのか考えています
UIスレッドでキューに入れられたPropertyChanged
晴れ
GC
WeakReferenceは参照を失います
PropertyChangedが解決され、例外がスローされるようになりました
多分それはこの問題に関連していますか?
https://github.com/xamarin/xamarin-android/issues/2049
@StephaneDelcroixは、この時点でいくつかの追加の洞察を持っている可能性があります:-)
昨夜は少し暇があったので、簡略化した再現でClear()
を呼び出した後、 GC.Collect()
追加してみました。 残念ながら、そのように問題を再現することはできませんでした。
それは本当に良い呼びかけです。 しかし悲しいことに、その後でも、 Clear()
は再現をトリガーしません。
では、一歩後退します...これはどのように機能する必要がありますか? バインディングが弱参照を保持している場合、定義上、そのオブジェクトはGCされる可能性があります。 だから、それはまあ、起こり得ることであり、XFはキャッチできない例外を投げるべきではありません。 代わりに、PropertyChanged通知を無視し、アプリが何をしているのかを知っていると信頼する必要があります。 つまり、他に何ができるのでしょうか?
試して再作成するために使用している再現を添付できますか?
今夜コードを添付します。 これは基本的に、スタンドアロンアプリに抽出された、すでに見たアプリ内の再現です。 しかし、私はまだその中で問題の再現を見ていません。
@PureWeen :これを診断するために他にできることはありますか?
@mfeingolは、スタンドアロンアプリで再現する方法がわからない限り、
https://github.com/xamarin/Xamarin.Forms/issues/6698#issuecomment -519359760で述べたように、これを概念的に考えることは可能ですか? それとも、実際に問題を引き起こしているものにまだ欠けている部分がありますか?
私は同じ問題を抱えており、それを簡単に再現することもできません)-:
@ysmoradi :簡単な再現をアップロードできるとは思いませんか?
私のプロダクションアプリでも再現するのは難しいです!
私も本番環境で@ PureWeenによると、単純な再現なしでは問題を理解するのは困難です。 私はそれを作成しようとしましたが失敗しました。 :-(
例外のメッセージにプロパティ名+ビュータイプ名+バインディングコンテキストのタイプ名を含めることをお勧めします。そうすれば、より良い洞察を得ることができます。
xamarinフォーム4.2.0.709249を使用して、iOSとAndroidでまったく同じ問題が発生しています。
xamlで定義されたオブジェクトを視覚化するためにDataTemplateを使用するListViewがあります。
xamlページでDataTypeを設定してから、リストビューデータテンプレートで別のDataTypeを設定しています。
バインドしているリストでclear、replace、またはanytingを呼び出す必要はありません。GC.Collectを呼び出して、上記のエラーが発生する別のメソッドを待つだけで十分なようです。 (GC.Collect呼び出しがない場合、失敗することはめったにありませんが、時々実行され、呼び出しは正常にロードされますが、更新時に失敗します。)
ただし、viewModel.IsBusyとlistview.IsRefreshingの間のバインディングを削除すると、何か面白いことがわかりました(ただし、もちろん、プルして更新した後も更新インジケーターは実行され続けます)。
また、コンテンツページのデータ型を削除し、それをデータテンプレートにのみ設定すると、エラーもなくなり、リストビューIsRefresingでバインディングを使用できます。
再現するために本番アプリに必要なものを要約すると、次のようになります。
@shoyheim :ここに投稿できる簡単な再現はありますか?
@shoyheim :ここに投稿できる簡単な再現はありますか?
@mfeingol申し訳ありませんが、本番コードをテスト/デバッグしています。 エラーを再現するために何かを作るために、しばらくの間絞ることができるかどうかを確認します...
@shoyheim :これで運が
@mfeingol
申し訳ありませんが、試してみましたが、単純な再現を行うたびにクラッシュさせることはできませんが、本番アプリがクラッシュし続けます。
これで、コンパイルされたバインディングをすべて削除し、xamlファイルでランタイムバインディングを使用するだけで、クラッシュがなくなりました。
私は何が悪いのかを理解するために多くの時間を費やしてきましたが、私が確信している唯一のことは、リストが更新されていることを示すために「isRefreshing」のバインディングでListViewを使用することと使用することの間に関係があるということですコンパイルされたバインディング...また、クラッシュはガベージコレクションの前後に発生するようです。
1-バインディングコンテキスト(ビューモデル)のプロパティが変更されます。
2-ビューをポップして破棄します。
3-GCが呼び出されます。
@ysmoradi :ステップを再現するのにしばらく時間を費やしましたが、クラッシュをトリガーできませんでした。 サンプルプロジェクトがあるとは思いません。
以前、単純なレポはなく、本番アプリで発生していると言いましたが、ランダムにも発生します。
初めてリポジトリを作成し始めたときは、あまり気づいていませんでしたが、明日は新しい仮定を使って別のリポジトリを作成しようと思います。
役立つ可能性のある別のヒント:私の仮定に基づくと、同時GCを有効にすると、クラッシュを再現する可能性が高くなります。 別のスレッドでオブジェクトを収集できるためです。 また、Device.BeginInvokeOnMainThreadは、メインスレッド以外のスレッドで呼び出された場合にのみ、アクションをメインスレッドのキューの最後に渡すため、別のスレッド/タスクでビューモデルのプロパティを変更する必要があります。
もう一度やり直して、何か見つけたら教えてください。明日やってみます。
並行GCを有効にしました。 あなたの提案を使用して、私が使用しているコードのスニペットはこれを行います:
Page1 page = new Page1();
await this.Navigation.PushModalAsync(page);
await Task.Run(() => { page.TXT = "Foo"; });
await this.Navigation.PopModalAsync();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
TXTは、BindablePropertyを使用して実装されたPage1のプロパティです。 Page1はコンパイルされたバインディングを使用しています。
まだ運がない。
私の本番アプリでも同じ問題がランダムに発生します。 パフォーマンスガイドラインで推奨されているように、x:Datatypeをどこにでも設定するという面倒なプロセスを経た後、この問題のためにそれらをすべて削除しなければならない可能性があることに興奮しているとは言えません。
うまくいくことができれば、これを再現アプリで更新します。
注:これが関連しているとは思えませんが、圧縮レイアウトも使い始めて初めて問題が発生したようです。 問題は非常にランダムであるため、おそらく偶然ですが、誰が知っていますか。
コンパイルされたバインディングを使用してアプリをMVVMに更新したところ、同じエラーが発生しました。
最新のXamarin.Formsの実行:4.2.0.848062
次の設定で:
また、再現手順はありません(このバージョンのアプリは、1日間ベータ版であり、AppCenter経由ですでに2つのレポートがあります)。
アプリリポジトリを共有できますが、再現手順がなければ、あまり役に立たないと思います。
全体像を理解していないかもしれませんが、TypedBinding.csでDO_NOT_CHECK_FOR_BINDING_REUSEが定義されていない場合のように、単に適用を解除してターゲットがGCされたときに戻るのは簡単な解決策ではありませんか? ここで投げるのがいかに良い考えかわかりません。
@fmanseau :私も同じ見方をしています。 @PureWeen?
また、それが役立つ場合は、Prismのリポジトリでこれに関連する問題に再現手順があるようです(Prismアプリが必要ですが、おそらく同じパターンに従うのは簡単です)。
@StephaneDelcroix @ kingces95 @wachs
皆さんはTypedBinding
実装の背後にいるようです。
このスレッドでわかるように、多くの開発者(私を含む)は、 TypedBinding
によってスローされたInvalidOperationException
原因で、アプリがクラッシュすることがあります。
@samhoutsは、GCが起動してTypedBinding
のtarget
を削除した後、(かなり大きなアプリの場合によくあることですが)、彼女の想定に正しいようです。 ListView
と多くの複雑なDataTemplates
)、 TypedBinding
はInvalidOperationException
をスローしますが、これはキャッチされず、Android(および場合によっては他のプラットフォーム)でアプリケーションがクラッシュします。 ??) このような:
TypedBinding
2[TSource,TProperty].Apply (System.Boolean fromTarget) System.InvalidOperationException: Operation is not valid due to the current state of the object. Stack traces TypedBinding
2 [TSource、TProperty] .Apply(System.Boolean fromTarget)
TypedBinding`2 + PropertyChangedProxy [TSource、TProperty]。b__16_0()
Thread + RunnableImplementor.Run()
IRunnableInvoker.n_Run(System.IntPtr jnienv、System.IntPtr native__this)
(ラッパー動的メソッド)Android.Runtime.DynamicMethodNameCounter.43(intptr、intptr)
@mfeingolは、結局このクラッシュを引き起こすInvalidOperationException
がある理由を合理的に尋ねます。 ターゲットをガベージコレクションすることは概念的に許可されていなかったということですが、なぜ弱い参照を使用するのですか?
私自身は.NET3.0以降のWPF開発者であり、バインディングの例外によってクラッシュが発生することはなく、ログに記録されるだけであることを知っています。
だから私の質問:
TypedBinding
が例外をスローし、ターゲットが収集された場合にそれを無視しない理由はありますか?
あるいは、バインディングシステム自体がすべてのバインディング例外をキャッチし、開発者がそれらを飲み込んだり、適切に対応したりできるようにする必要がありますか?
これは本番アプリにとって本当に重要なバグであり、必要に応じて、これを修正する中間のXamarin.Formsリリースを作成します。 しかし、そのために、これがどのような望ましくない影響を与える可能性があるのか知りたいです!
@ bruzkovsky-これもあなたの興味を引くかもしれません
また、 @ StephaneDelcroix @ kingces95 @wachs 、旗が見えますDO_NOT_CHECK_FOR_BINDING_REUSE
正確には何のためですか?
このバグを取り除くために、 DO_NOT_CHECK_FOR_BINDING_REUSE
をtrue
に設定してXamarin.Formsをコンパイルしたいと思います。
しかし、その背後にある思考プロセスは何ですか? この旗を掲げるのには十分な理由があるはずですよね?
これは、ListViewとDataTemplateSelectorを備えた単純なContentPageで発生したばかりです。
この問題に関する更新はありますか?
この問題が未解決の場合、コンパイルされたバインディングを使用することが現在推奨されているのはなぜですか?
https://docs.microsoft.com/es-es/xamarin/xamarin-forms/app-fundamentals/data-binding/compiled-bindings
@mrjavicho :問題を一貫して再現する簡単なプロジェクトを投稿できる可能性はありますか?
このサンプルで問題を頻繁に再現することができました。
https://github.com/usausa/TypedBindingIssue
アプリケーションを実行し、[テスト]ボタンをクリックします。
また、MainPage.Cleanup()でコメントを削除しても、問題は発生しません。
これは、 @ usausaのコードを使用して
0x16 in Xamarin.Forms.Internals.TypedBinding<TypedBindingIssueApp.View1ViewModel,string>.Apply at D:\a\1\s\Xamarin.Forms.Core\TypedBinding.cs:99,5 C# Annotated Frame
0x7 in Xamarin.Forms.Internals.TypedBinding<TypedBindingIssueApp.View1ViewModel,string>.PropertyChangedProxy.<OnPropertyChanged>b__16_0 at D:\a\1\s\Xamarin.Forms.Core\TypedBinding.cs:277,31 C# Annotated Frame
0x29 in Xamarin.Forms.DispatcherExtensions.Dispatch at D:\a\1\s\Xamarin.Forms.Core\DispatcherExtensions.cs:53,6 C# Annotated Frame
0x3F in Xamarin.Forms.Internals.TypedBinding<TypedBindingIssueApp.View1ViewModel,string>.PropertyChangedProxy.OnPropertyChanged at D:\a\1\s\Xamarin.Forms.Core\TypedBinding.cs:277,5 C# Annotated Frame
0x15 in Xamarin.Forms.BindingExpression.WeakPropertyChangedProxy.OnPropertyChanged at D:\a\1\s\Xamarin.Forms.Core\BindingExpression.cs:645,6 C# Annotated Frame
> 0x14 in TypedBindingIssueApp.NotificationObject.RaisePropertyChanged at C:\Operations\Build\External\TypedBindingIssue\TypedBindingIssueApp\TypedBindingIssueApp\NotificationObject.cs:13,13 C# Symbols loaded.
0x5D in TypedBindingIssueApp.LongLifecycleModel.Next at C:\Operations\Build\External\TypedBindingIssue\TypedBindingIssueApp\TypedBindingIssueApp\LongLifecycleModel.cs:19,13 C# Symbols loaded.
0x2A in TypedBindingIssueApp.MainPage.Button_OnClicked at C:\Operations\Build\External\TypedBindingIssue\TypedBindingIssueApp\TypedBindingIssueApp\MainPage.xaml.cs:29,17 C# Symbols loaded.
0x6 in System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext at /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1092,17 C# Annotated Frame
0x73 in System.Threading.ExecutionContext.RunInternal at /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:968,17 C# Annotated Frame
0x4 in System.Threading.ExecutionContext.Run at /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:910,13 C# Annotated Frame
0x32 in System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run at /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1073,25 C# Annotated Frame
0x6 in System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.<>c.<.cctor>b__7_0 at /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs:379,78 C# Annotated Frame
0xC in Android.App.SyncContext. C# Annotated Frame
再現はスポットです! 私が最初に気付いたのは、クラッシュが完全にランダムな時間に発生し、ボタンを複数回押して待機することもあったので、少し調整してクラッシュを早くしました(一貫して29エンティティの後):
このようにPCイベントを80回発生させるだけです。
c#
for (var i = 0; i < 80; i++)
RaisePropertyChanged(nameof(Entity));
これにより、ディスパッチャに対してより多くのイベントがスケジュールされ、失敗率が高くなります。
View1
View2
クラスとNullReferenceException
スローされます。
まだ簡単な回避策を探しています...
最も参考になるコメント
@StephaneDelcroix @ kingces95 @wachs
皆さんは
TypedBinding
実装の背後にいるようです。このスレッドでわかるように、多くの開発者(私を含む)は、
TypedBinding
によってスローされたInvalidOperationException
原因で、アプリがクラッシュすることがあります。@samhoutsは、GCが起動して
TypedBinding
のtarget
を削除した後、(かなり大きなアプリの場合によくあることですが)、彼女の想定に正しいようです。ListView
と多くの複雑なDataTemplates
)、TypedBinding
はInvalidOperationException
をスローしますが、これはキャッチされず、Android(および場合によっては他のプラットフォーム)でアプリケーションがクラッシュします。 ??) このような:@mfeingolは、結局このクラッシュを引き起こす
InvalidOperationException
がある理由を合理的に尋ねます。 ターゲットをガベージコレクションすることは概念的に許可されていなかったということですが、なぜ弱い参照を使用するのですか?私自身は.NET3.0以降のWPF開発者であり、バインディングの例外によってクラッシュが発生することはなく、ログに記録されるだけであることを知っています。
だから私の質問:
TypedBinding
が例外をスローし、ターゲットが収集された場合にそれを無視しない理由はありますか?あるいは、バインディングシステム自体がすべてのバインディング例外をキャッチし、開発者がそれらを飲み込んだり、適切に対応したりできるようにする必要がありますか?
これは本番アプリにとって本当に重要なバグであり、必要に応じて、これを修正する中間のXamarin.Formsリリースを作成します。 しかし、そのために、これがどのような望ましくない影響を与える可能性があるのか知りたいです!
@ bruzkovsky-これもあなたの興味を引くかもしれません