あなたが見つけた記事は、私たちの大部分のようにコールスタックがうまくいかない理由を説明してくれます。技術的には、コールスタックは、コードが現在のメソッドの後にどこに戻ってくるかを伝えます。言い換えれば、コールスタックは「コードがどこから来たか」ではなく、「コードがどこに行くのか」です。興味深いことに、この記事では合格の解決策について言及していますが、解説しません。私はa blog post that goes explains the CallContext
solution in detailです。基本的には、論理コールコンテキストを使用して独自の「診断コンテキスト」を作成します。
は、私はそれが仕事が
async
コードのすべての形式(
Task.WhenAll
のようなコードに参加/フォークを含む)になるんので、記事で紹介したソリューションよりも
CallContext
ソリューションの方が好き。
これは私が知っている最良の解決策です(プロファイリングAPIへのフックのような非常に複雑なこと以外)。 CallContext
の警告:
- これは.NET 4.5でのみ動作します。 Windows Storeアプリケーション、.NET 4.0などはサポートされていません
- コードを手動でインストルメントする必要があります。 AFAIKを自動的に挿入する方法はありません。
- 例外は、論理呼び出しコンテキストを自動的に取得しません。したがって、例外がスローされたときにデバッガに侵入している場合、このソリューションは正常に動作しますが、別の場所で例外をキャッチしてログに記録するだけではそれほど役に立ちません。
コード(immutable collections NuGet libraryに依存します):
public static class MyStack
{
private static readonly string name = Guid.NewGuid().ToString("N");
private static ImmutableStack<string> CurrentContext
{
get
{
var ret = CallContext.LogicalGetData(name) as ImmutableStack<string>;
return ret ?? ImmutableStack.Create<string>();
}
set
{
CallContext.LogicalSetData(name, value);
}
}
public static IDisposable Push([CallerMemberName] string context = "")
{
CurrentContext = CurrentContext.Push(context);
return new PopWhenDisposed();
}
private static void Pop()
{
CurrentContext = CurrentContext.Pop();
}
private sealed class PopWhenDisposed : IDisposable
{
private bool disposed;
public void Dispose()
{
if (disposed)
return;
Pop();
disposed = true;
}
}
// Keep this in your watch window.
public static string CurrentStack
{
get
{
return string.Join(" ", CurrentContext.Reverse());
}
}
}
使用法:
static async Task SomeWorkAsync()
{
using (MyStack.Push()) // Pushes "SomeWorkAsync"
{
...
}
}
アップデート:私は自動的にプッシュとポップを注入するPostSharpを使用するNuGet package (described on my blog)をリリースしました。だから、良いトレースを得ることはもっと簡単になるはずです。
ありがとうございました。私はそれがどのように動作するか試してみます:-)。私は何とか 'Paralell Stack'のような解決策がもっとあると期待していました。しかし、あなたはすべてを持つことはできません;-)。私は 'MyStack.Push()'ログだけを修正して、私がどこにいたのか知りたいのならどこでも必要ですか? – Patrick
'MyStack.Push'と' MyStack.Pop'(処分)はスタックを変更します。はい、どこにでも追加する必要があります。 :(VS2012は「async」をサポートする最初のリリースです;将来的にはより良いデバッグサポートを得ることができます) –
あなたは本当のところから来たものを知っているので、デバッグに違いがあります^^。あなたのブログがいいから時間を見つけた時に読んでくれる便利なエントリーがあるので最適化したいと思うかもしれません。 。 – Patrick