34

次のように宣言された log4net を使用します。

private readonly ILog log = 
       LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType());

次のような非同期メソッドまたはタスクで:

public async void CheckSomething()
{
    log.Info(null);
    //....
}

MoveNextの代わりにログを記録しCheckSomethingます。実際のメソッド名をログに記録する方法はありますか?

4

7 に答える 7

32

すべてのasyncメソッドは、メソッド内の潜在的な値を満たすためにステート マシンに書き直されawaitます。コードが存在する最後のメソッドは、レポート するMoveNextメソッドです。log4net

MoveNext実行時に、コードが最初に記述された実際のメソッドに移行する良い方法は実際にはありません。それらはメタデータ レベルで多少切り離されています。名前を直接ログに記録する必要があるかもしれません

于 2014-03-24T01:29:25.070 に答える
12

短いMoveNext():メソッドが与えられたら、これを試してください:

private static MethodBase GetRealMethodFromAsyncMethod(MethodBase asyncMethod)
{
    var generatedType = asyncMethod.DeclaringType;
    var originalType = generatedType.DeclaringType;
    var matchingMethods = 
        from methodInfo in originalType.GetMethods() 
        let attr = methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() 
        where attr != null && attr.StateMachineType == generatedType 
        select methodInfo;

    // If this throws, the async method scanning failed.
    var foundMethod = matchingMethods.Single();
    return foundMethod;
}

ロング (免責事項)

これを本番環境で使用しないでください。これはコンパイラの動作に依存しており、将来のバージョンでは予告なく変更される可能性があります。コンパイラに関する次の仮定が行われます。

  1. 実際に実行中の非同期メソッドは、生成された型の内部で生成されます。
  2. 生成された型は、元の手書きのメソッドを含む元の型の入れ子になった型です。
  3. 元のメソッドは、コンパイラによって生成された属性 AsyncStateMachine を取得し、生成された型が提供されます。

私のコードで動作し、デバッグ/テスト中の実行時コード分析にのみ使用します。繰り返しますが、製品コードでは使用しないでください。

于 2015-02-20T16:01:27.900 に答える