gpt4 book ai didi

c# - 为函数制作时间测量包装类的最佳方法是什么?

转载 作者:行者123 更新时间:2023-11-30 18:17:35 48 4
gpt4 key购买 nike

我想开始测量函数在我的程序中的多个位置运行所花费的时间。

处理 StopWatch 的代码似乎有点困惑,所以我决定将其包装起来。

这些是我需要的东西:

  • 该函数将接收一个可能有也可能没有返回值的异步函数
  • 我需要从函数中取出两件事:返回值(如果存在)和它运行所花费的时间(以秒为单位)

我想找到一个可读且可持续的解决方案,因为它将用于多个项目。


这是我到目前为止所做的:

public class TimeMeasurer 
{
private readonly Stopwatch _stopWatch;

public TimeMeasurer()
{
_stopWatch = new Stopwatch();
}

public async Task<Tuple<double, TReturn>> Start<TReturn>(Func<Task<TReturn>> function)
{
try
{
_stopWatch.Start();
var val = await function();
var took = _stopWatch.Elapsed.TotalSeconds;

return Tuple.Create(took, val);
}
finally
{
_stopWatch.Stop();
_stopWatch.Reset();
}
}

public async Task<double> Start(Func<Task> function)
{
try
{
_stopWatch.Start();
await function();
var took = _stopWatch.Elapsed.TotalSeconds;

return took;
}
finally
{
_stopWatch.Stop();
_stopWatch.Reset();
}
}
}

如果没有更好的解决方案..

  • 有没有办法合并这两个功能? (一个包含返回值,第二个获取 void 函数)
  • 有没有办法返回比元组更清晰的东西?我觉得处理起来有点麻烦

编辑:调用我创建的类看起来也不太好..

var tuple = await _timeMeasurer.Start(async () => await function(param1, param2));

编辑:我决定放弃这个想法。太乱了。最后我使用 StopWatch

最佳答案

对于你的第一点,你可以做的不多,可以组合这些功能,只是没有太多的逻辑可以组合。

对于你的第二点,我会创建两个自定义类来保存结果。您也可以想象并进行一些继承,并返回整个任务对象,而不仅仅是结果,以防有人想查看返回任务的某些属性。

最后,你的函数没有理由应该是一个实例,整个类都可以是静态的。

这是一个包含我建议的更改的示例。

public class TimeMeasurerResult
{
protected readonly Task _task;
private readonly TimeSpan _duration;

public TimeMeasurerResult(Task task, TimeSpan duration)
{
_task = task;
_duration = duration;
}

public Task Task {get { return _task;}}
public TimeSpan Duration {get {return _duration;}}
}

public class TimeMeasurerResult<T> : TimeMeasurerResult
{
public TimeMeasurerResult(Task<T> task, TimeSpan duration)
:base(task, duration)
{
}

public T Result {get { return ((Task<T>)_task).Result;}}
}

public static class TimeMeasurer
{
public static async Task<TimeMeasurerResult<TReturn>> Start<TReturn>(Func<Task<TReturn>> function)
{
var stopWatch = Stopwatch.StartNew();
var task = function();
await task;
var took = stopWatch.Elapsed;

return new TimeMeasurerResult<TReturn>(task, took);
}

public static async Task<TimeMeasurerResult> Start(Func<Task> function)
{
var stopWatch = Stopwatch.StartNew();
var task = function();
await task;
var took = stopWatch.Elapsed;

return new TimeMeasurerResult(task, took);
}
}

这是一个 using it 的例子,注意我只需要做 var results = await TimeMeasurer.Start(() => Function(a,b)); 而不是 var results = await TimeMeasurer.Start(async () => await Function(a,b));

public class Program
{
public static void Main()
{
AsyncMain().Wait();
}

public static async Task AsyncMain()
{
int a = 500;
int b = 10;
var results = await TimeMeasurer.Start(() => Function(a,b));
Console.WriteLine("Waited: {0}", results.Duration.TotalSeconds);
Console.WriteLine("Result: {0}", results.Result);
}

public static async Task<int> Function(int a, int b)
{
var total = a + b;
await Task.Delay(total);
return total;
}
}

关于c# - 为函数制作时间测量包装类的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43307599/

48 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com