以下は、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を返すかどうかを返すメソッドでのみ機能しますが、私はそれで問題ありません。TaskTask<>void
が元の呼び出し元ではなくそこに戻るようにするには、Interceptメソッド内でどのような変更を加える必要がありますか?awaiter