Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用IDisposable+;测量经过时间的计时器_C#_Idisposable_Stopwatch - Fatal编程技术网

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