CIL:“操作によりランタイムが不安定になる可能性があります”例外
-
03-07-2019 - |
質問
PostSharpを少し使ってみましたが、厄介な問題に遭遇しました。
SilverlightアセンブリのILに従う:
.method public hidebysig specialname newslot virtual final instance void
set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
.maxstack 2
.locals (
[0] bool ~propertyHasChanged,
[1] bool CS$4public void set_AccountProfileModifiedAt(DateTime value)
{
bool propertyHasChanged = this.AccountProfileModifiedAt != value;
this.accountProfileModifiedAt = value;
if (propertyHasChanged)
{
this.NotifyPropertyChanged("AccountProfileModifiedAt");
}
}
)
L_0000: nop
L_0001: nop
L_0002: ldarg.0
L_0003: call instance valuetype [mscorlib]System.DateTime
Accounts.AccountOwner::get_AccountProfileModifiedAt()
L_0008: ldarg.1
L_0009: call bool [mscorlib]System.DateTime::op_Inequality(valuetype
[mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime)
L_000e: stloc.0
L_000f: ldarg.0
L_0010: ldarg.1
L_0011: stfld valuetype [mscorlib]System.DateTime
Accounts.AccountOwner::accountProfileModifiedAt
L_0016: br.s L_0018
L_0018: ldloc.0
L_0019: ldc.i4.0
L_001a: ceq
L_001c: stloc.1
L_001d: ldloc.1
L_001e: brtrue.s L_002b
L_0020: ldarg.0
L_0021: ldstr "AccountProfileModifiedAt"
L_0026: call instance void
Accounts.AccountOwner::NotifyPropertyChanged(string)
L_002b: nop
L_002c: leave.s L_002e
L_002e: ret
}
トリガーSystem.Security.VerificationException:操作によりランタイムが不安定になる可能性があります。例外。 Reflectorはそれを解析します。何が問題なのでしょうか?
更新1 コードは次のように機能することを目的としています。
L_0018: ldloc.0
L_0019: ldc.i4.0
L_001a: ceq
L_001c: stloc.1
L_001d: ldloc.1
更新2 セッター自体の内部で指定された例外を受け取ります
更新3 callvirt(NotifyPropertyChanged)として非静的呼び出しを行うことは役に立ちません
更新4 (テスト目的の)コードのコメントアウト:
.method public hidebysig specialname newslot virtual final instance void
set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
.maxstack 2
.locals init (
[0] bool val,
[1] bool CS$4<*>)
L_0000: nop
L_0001: ldarg.0
L_0002: call instance valuetype [mscorlib]System.DateTime
Accounts.AccountOwner::get_AccountProfileModifiedAt()
L_0007: ldarg.1
L_0008: call bool [mscorlib]System.DateTime::op_Inequality(valuetype
[mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime)
L_000d: stloc.0
L_000e: ldarg.0
L_000f: ldarg.1
L_0010: stfld valuetype [mscorlib]System.DateTime
Accounts.AccountOwner::accountProfileModifiedAt
L_0015: ldloc.0
L_0016: ldc.i4.0
L_0017: ceq
L_0019: stloc.1
L_001a: ldloc.1
L_001b: brtrue.s L_0029
L_001d: ldarg.0
L_001e: ldstr "AccountProfileModifiedAt"
L_0023: call instance void
Accounts.AccountOwner::NotifyPropertyChanged(string)
L_0028: nop
L_0029: ret
}
L_001e:brtrue.s L_002bをL_001e:br.s L_002bに置き換えると、トリックを実行できますが、無条件に戻ります-私が望むものではありません。
アップデート5 C#コンパイラを使用して必要な動作を模倣する場合(Postsharpでそれを行う必要があります) 次のILを取得します。
<*>小さな違いがあることに注意してください-L_0016での追加のbr.sジャンプといくつかの奇妙なジャンプL_001e:brtrue.s L_002b。コンパイラバージョンでは、retに直接ジャンプします。
解決
peverifyを使用しましたか? MSILを直接使用する場合は、常にこのユーティリティを実行する必要があります(msbuildフラグ/ p:PostSharpVerify = trueを使用できます)。
コードを見る:
-
ローカル変数は初期化されていません(&quot; init&quot;キーワードがありません)。これは、MethodBodyDeclarationのプロパティです。
-
保護ブロックから「jmp」の代わりに「leave」を使用しています。これは役に立ちませんが、問題ではありません。
幸運を祈ります
-gael
他のヒント
言うのは難しい-スタックトレースはありますか?この例外は通常、CLRがコードの型安全性を検証できない場合にスローされます。これはこのコードまたは使用しているメソッドまたはタイプのいずれかから発生した可能性があるため、スタックトレースなしで問題が何であるかを言うのは困難です。
こちらは、そのエラーを扱った投稿です。あなたの特定のケースが同じ問題によって引き起こされているかどうかはわかりませんが、一般的にこれはコードアクセスのセキュリティと検証に関係しているようです。その場合、ReflectorはILを正常に読み取ることができますが、CASシステムは未知の理由でそれを追い出します。
他の多くのオブジェクトを呼び出すプロパティセッターがあるようです。ポストで言及されている特定の問題の場合は、大きなswitchステートメントを探して他のメソッド呼び出しを実行する必要があります。