【发布时间】:2017-09-06 12:35:57
【问题描述】:
我做了这个 hacky 变通方法来为我的一些异步 api 调用添加前/后日志记录。
是否有更简洁/更好的方法来编写 void Task 的重载?
这种方法一般有什么问题吗?有任何建议的更改吗?
public static Task<TResult> LogAsyncTask<TResult>
(this Task<TResult> task, string messageTemplate,
LogEventLevel level = LogEventLevel.Information)
{
Log.Write(level, "Async Starting: " + messageTemplate);
return task.ContinueWith(antecedent =>
{
var result = antecedent.GetAwaiter().GetResult();
Log.Write(level, "Async Finished: " + messageTemplate);
return result;
});
}
public static Task<object> LogAsyncTask
(this Task task, string messageTemplate,
LogEventLevel level = LogEventLevel.Information)
=> Task<object>.Factory.StartNew(() =>
{
task.GetAwaiter().GetResult();
return null;
}).LogAsyncTask(messageTemplate, level);
你是这样称呼它的:
await apiClient.MySoapMethodAsync().LogAsyncTask("Doing MySoapMethod...");
【问题讨论】:
-
我看到这段代码的一个明显问题是,就其本质而言,它必须是谎言。如果您正在使用热任务调用方法(您的代码假定它只调用
ContinueWith而不是Start),那么当您输出“Starting”时,该任务已经开始,甚至可能实际上已经开始已经完成了。 -
Fildor,它使用 serilog。达米安,是的,我对此很好,这主要用于可能最终需要 1 秒以上的肥皂电话,只是为了跟踪任何长时间运行的电话。我知道日志行可能会在方法启动后被调用,但通常不会在我们的案例中对时间产生实质性影响。
-
是的,我以为我看到了一个语法错误,但那是我的老脏眼睛......你只想测量往返时间还是你也想插入某种时间 -以后会出功能吗?
-
这纯粹是为了测量。我什至使用 awaiter 以便它会重新抛出任何错误。
标签: c# task overloading extension-methods