使用IDisposable +计时器测量经过的时间

问题描述 投票:-1回答:1

我有一些代码可以做很多工作。它在足够的时间内完成了足够的工作,我们通常不关心精确的准确度(即毫秒),但是关闭超过一分钟是没有用的。我们有一个存储过程,我们调用它来记录任务的开始和任务的结束。现在我们有很多代码如下:

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停止它)

using (new Logger(taskName, debug))
{
    // Do stuff
}

尽我们所知,这应该只是编译到这个:

Logger loggerThing = null;
try
{
    loggerThing = new Logger(taskName, debug);
    // Do stuff
}
finally
{
    loggerThing?.Dispose();
}

因此,将这个用于我们的大型任务似乎是相当安全的,其具有足够的粒度以能够说“运行合理的时间量”或“运行得比正常情况快得多/慢”。我们对不对?

从一些阅读中,我发现了以下文章,代码示例和SO Q&A。我们显然并不是唯一一个想到这个或类似事物的人,但似乎没有人能够对“我们如何及时地假设Dispose将会被调用以及如何可靠的问题”做出明确而明确的回答时间结果是什么?“鉴于下面的第一篇文章,关于using如何只是语法糖,我们倾向于认为情况就是这样。

c# idisposable stopwatch
1个回答
0
投票

在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方法。

© www.soinside.com 2019 - 2024. All rights reserved.