【发布时间】:2020-01-28 02:21:12
【问题描述】:
我有几个由 API 提供给我的方法。我希望编写一个方便的助手来记录所述方法的执行时间,以及一般的任何代码块。
用例方法通常如下所示:
object GetData(string statementKey, string parametersJson, out string errorMessage);
Task<object> GetDataAsync(string statementKey, string parametersJson, CancellationToken cancellationToken = default(CancellationToken));
我为同步方法写了一个方法包装器:
public static T With<T>(string message, Func<T> func)
{
var watch = new Stopwatch();
T returned;
watch.Start();
try
{
returned = func.Invoke();
}
catch (Exception exception)
{
Log.Logger.Error(exception, $"Error in {message}");
throw;
}
finally
{
watch.Stop();
}
// Logging logic here
return returned;
}
(我知道这不适用于 void 方法,但如果操作是同步的,则操作重载是微不足道的)。
现在如果传递的方法是异步的,我会测量不准确的执行时间。我对如何更改上述方法以使用异步方法感到有些困惑。
我试过这个实现,但感觉不对。
public static async Task<T> AsyncWith<T>(string message, Func<Task<T>> func)
{
T returned;
try
{
var watch = new Stopwatch();
watch.Start();
returned = await func.Invoke().ConfigureAwait(false);
watch.Stop();
// Logging logic here
}
catch (Exception exception)
{
Log.Logger.Error(exception, $"Error in {message}");
throw;
}
return returned;
}
我真的不应该开始一个任务吗?我不明白为什么它使用T returned 而不是Task<T> returned 进行编译
【问题讨论】:
-
Shouldn't I start a task actually ?- 任务应该由func启动。从技术上讲,func可能会返回一个尚未开始的任务,但这会奇怪。I don't understand why it is compiling with T returned instead of Task<T> returned- 因为您已将AsyncWith标记为async。在标记为async的方法中,您return是在Task<T>中声明的类型。 -
什么意思 - 时间不准确?当来自 func 的任务完成时,等待任务将运行 watch.Stop() - 这意味着它将测量 func 的正确执行时间。
-
@vasiloreshenski 如果我将上面编写的 With
方法与异步委托一起使用,finally 块可能会在异步委托调用完成之前执行,我不会测量执行时间异步方法。因此需要一个异步方法。 -
@FooBar 在底层,编译器将异步方法转换为状态机like this。
标签: c# .net async-await