以下は、Castle Dynamic ProxyライブラリIntercept
を実装するカスタム型のメソッドのコードです。このスニペットは、ここに投稿されているAOPベースのロギング概念実証コンソール アプリからのものです。IInterceptor
public void Intercept(IInvocation invocation)
{
if (Log.IsDebugEnabled) Log.Debug(CreateInvocationLogString("Called", invocation));
try
{
invocation.Proceed();
if (Log.IsDebugEnabled)
if (invocation.Method.ReturnType != typeof(void))
Log.Debug("Returning with: " + invocation.ReturnValue);
}
catch (Exception ex)
{
if (Log.IsErrorEnabled) Log.Error(CreateInvocationLogString("ERROR", invocation), ex);
throw;
}
}
これは、通常のメソッド呼び出しでは期待どおりに機能しますが、メソッドで試した場合( C# 5.0async
のキーワードを使用) には機能しません。async/await
そして、私はこの背後にある理由も理解していると信じています.
が機能するために、コンパイラはメソッドの機能本体をバックグラウンドでステート マシンに追加し、同期的に完了できないasync/await
最初の式が検出されるとすぐに、制御が呼び出し元に戻ります。awaitable
async
また、戻り値の型を調べて、次のようなメソッドを扱っているかどうかを判断できます。
if (invocation.Method.ReturnType == typeof(Task) ||
(invocation.Method.ReturnType.IsGenericType &&
invocation.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)))
Log.Info("Asynchronous method found...");
これは、どちらかasync
を返すかどうかを返すメソッドでのみ機能しますが、私はそれで問題ありません。Task
Task<>
void
が元の呼び出し元ではなくそこに戻るようにするには、Intercept
メソッド内でどのような変更を加える必要がありますか?awaiter