C# 使用IDisposable+;测量经过时间的计时器
我有一些代码可以做很多工作。它在足够长的时间内完成了足够多的工作,因此我们通常不关心精确性(即毫秒),但如果关闭时间超过一分钟则没有用处。我们调用了一个存储过程来记录任务的开始和结束。现在我们有很多代码如下所示:C# 使用IDisposable+;测量经过时间的计时器,c#,idisposable,stopwatch,C#,Idisposable,Stopwatch,我有一些代码可以做很多工作。它在足够长的时间内完成了足够多的工作,因此我们通常不关心精确性(即毫秒),但如果关闭时间超过一分钟则没有用处。我们调用了一个存储过程来记录任务的开始和结束。现在我们有很多代码如下所示: Logger.LogTaskStart(taskName); // do stuff Logger.LogTaskEnd(taskName); 这两个方法保存元数据,元数据最终通过上述存储过程持久化。我们也有一些地方,我们有时可能会记录定时信息,但不总是b/c,这要么是太多的噪音,要
Logger.LogTaskStart(taskName);
// do stuff
Logger.LogTaskEnd(taskName);
这两个方法保存元数据,元数据最终通过上述存储过程持久化。我们也有一些地方,我们有时可能会记录定时信息,但不总是b/c,这要么是太多的噪音,要么通常没有问题
if (debug) Logger.LogTaskStart(taskName);
// do stuff
if (debug) Logger.LogTaskEnd(taskName);
我们曾经遇到过这样的问题:我们无意中使开始和结束不匹配,或者我们只将一个放在调试标志下,等等。我们考虑过创建一个非常简单的记录器类,实现IDisposable来为我们实现它,这样我们就可以这样做(假设构造函数启动计时器RAII样式,Dispose停止它)
就我们所知,这应该编译成大约:
Logger loggerThing = null;
try
{
loggerThing = new Logger(taskName, debug);
// Do stuff
}
finally
{
loggerThing?.Dispose();
}
因此,将其用于粒度足够大的任务似乎相当安全,可以说“运行了合理的时间”或“比正常运行速度快/慢”。我们说得对吗
通过阅读,我发现了以下文章、代码示例和问答。显然,我们不是唯一想到这一点或类似问题的人,但似乎没有人对“我们可以假设调用Dispose的时间有多及时,以及调用的计时结果有多可靠”这一问题给出明确的答案在下面的第一篇文章中,关于如何使用只是语法上的糖分,我们倾向于这样认为
在using语句中的代码之后立即调用Dispose方法。为了确认这一点,我们可以查看一下由using语句生成的IL:
下面是一个简单的例子:
class Program
{
static void Main()
{
using (new TestClass())
{
Console.WriteLine("Do work");
}
}
}
class TestClass : IDisposable
{
public void Dispose()
{
Console.WriteLine("disposed");
}
}
生成以下IL
Program.Main:
IL_0000: nop
IL_0001: newobj UserQuery+TestClass..ctor
IL_0006: stloc.0
IL_0007: nop
IL_0008: ldstr "Do work"
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: nop
IL_0014: leave.s IL_0021
IL_0016: ldloc.0
IL_0017: brfalse.s IL_0020
IL_0019: ldloc.0
IL_001A: callvirt System.IDisposable.Dispose
IL_001F: nop
IL_0020: endfinally
IL_0021: ret
Program..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: nop
IL_0007: ret
TestClass.Dispose:
IL_0000: nop
IL_0001: ldstr "disposed"
IL_0006: call System.Console.WriteLine
IL_000B: nop
IL_000C: ret
TestClass..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: nop
IL_0007: ret
在这里,我们可以看到在using语句中的代码之后立即调用dispose方法。因此,显然您有理由不相信您链接到的from问题。。。但是为什么呢?要向您澄清如何使用调用Dispose
,您到底缺少什么?您所说的及时是什么意思?将在using块的末尾调用Dispose。
Program.Main:
IL_0000: nop
IL_0001: newobj UserQuery+TestClass..ctor
IL_0006: stloc.0
IL_0007: nop
IL_0008: ldstr "Do work"
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: nop
IL_0014: leave.s IL_0021
IL_0016: ldloc.0
IL_0017: brfalse.s IL_0020
IL_0019: ldloc.0
IL_001A: callvirt System.IDisposable.Dispose
IL_001F: nop
IL_0020: endfinally
IL_0021: ret
Program..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: nop
IL_0007: ret
TestClass.Dispose:
IL_0000: nop
IL_0001: ldstr "disposed"
IL_0006: call System.Console.WriteLine
IL_000B: nop
IL_000C: ret
TestClass..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: nop
IL_0007: ret