今、私は最初の場所でMarshal.GetExceptionCode()
を使用するハックだけど、問題はそれについてではありません(Visual Studioのデバッガはまた、アクティブな例外を検出)例外非同期メソッドに巻き込まれた後
private static async Task TestAsync()
{
Log("TestAsync.Before");
await HandleExceptionAsync();
Log("TestAsync.After");
}
private static async Task HandleExceptionAsync()
{
try
{
Log("HandleExceptionAsync.Try");
await ThrowAsync();
}
catch (InvalidOperationException)
{
Log("HandleExceptionAsync.Catch");
}
Log("HandleExceptionAsync.AfterCatch");
}
private static async Task ThrowAsync()
{
await Task.Delay(1000);
throw new InvalidOperationException("Delayed exception");
}
private static void Log(string step)
{
Console.WriteLine($"{step}: {Marshal.GetExceptionCode()}");
}
出力
TestAsync.Before: 0
HandleExceptionAsync.Try: 0
Exception thrown: 'System.InvalidOperationException' in Interactive.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.ni.dll
HandleExceptionAsync.Catch: -532462766
HandleExceptionAsync.AfterCatch: -532462766
TestAsync.After: -532462766
The thread 9292 has exited with code 0 (0x0).
例外は、それがキャッチされていてもかかわらのawaitチェーン全体でアクティブなままとなります。 私は、生成されたコードをチェックして、なぜこれが起こっていることが手掛かりを与えていない、(HandleExceptionAsync
ステートマシンのMoveNext
を生成)関連部分:
void IAsyncStateMachine.MoveNext()
{
int num1 = this.\u003C\u003E1__state;
try
{
if (num1 == 0)
;
try
{
TaskAwaiter awaiter;
int num2;
if (num1 != 0)
{
Program.Log("HandleExceptionAsync.Try");
awaiter = Program.ThrowAsync().GetAwaiter();
if (!awaiter.IsCompleted)
{
this.\u003C\u003E1__state = num2 = 0;
this.\u003C\u003Eu__1 = awaiter;
Program.\u003CHandleExceptionAsync\u003Ed__1 stateMachine = this;
this.\u003C\u003Et__builder.AwaitUnsafeOnCompleted<TaskAwaiter, Program.\u003CHandleExceptionAsync\u003Ed__1>(ref awaiter, ref stateMachine);
return;
}
}
else
{
awaiter = this.\u003C\u003Eu__1;
this.\u003C\u003Eu__1 = new TaskAwaiter();
this.\u003C\u003E1__state = num2 = -1;
}
awaiter.GetResult();
awaiter = new TaskAwaiter();
}
catch (InvalidOperationException ex)
{
Program.Log("HandleExceptionAsync.Catch");
}
Program.Log("HandleExceptionAsync.AfterCatch");
}
catch (Exception ex)
{
this.\u003C\u003E1__state = -2;
this.\u003C\u003Et__builder.SetException(ex);
return;
}
this.\u003C\u003E1__state = -2;
this.\u003C\u003Et__builder.SetResult();
}
私はこれを同期コンテキストに関連しているが表示されませんいずれか(この場合はコンソールアプリケーションなので、継続はプール上でスケジュールされます)、私の最高の推測では、いくつかのコールスタック操作が起こっていますが、私はこれに関する良い情報を見つけることができません。
誰もがこれが起こっている理由を説明し、これは、CLR /コンパイラUPD1に実装されている方法を説明するドキュメントへのリンクを提供することができれば、私は感謝し
:でアクティブな例外を示すVSデバッガのを追加しましたスクリーンショット非同期、同期には何も示さない
'GetExceptionCode'には[構造化例外ハンドラのフィルタの外で動作が定義されていません](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679356(v = vs.85))があります。 aspx)。捕捉された後で「アクティブ」例外が発生するシナリオがある場合は、問題の再現を投稿してください。 –
@StephenClearyこの特定のコードは、VSデバッガ(例外変数)で例外をアクティブとして示しています。これはあなたのために書いてくれませんか? –
私には、「アクティブ」とはそれがスローされていることを意味します(または、長期間使用された場合)。このような動作をしていますか、 '$ exception'デバッガ変数ですか? –