Я использую Stopwatch
таймер для засекания времени выполнения участков кода в функциях моих проектов. По-хорошему, перед выходом из функции, в которой я использовал таймер, я должен его остановить. Но иногда в функции очень много мест выхода из функции, и не очень удобно останавливать таймер перед каждым таким return
-ом.
Вопрос - чревато ли это какими-то осложнениями - выйти из функции и не остановить таймер, или это не важно, т.к. локальный экземпляр таймера будет уничтожен (а может и нет) сборщиком мусора при выходе из функции?
Это обычный класс и судьба его за пределами области видимости переменной совершенно обычная.
Никаких осложнений типа "вдруг не остановив таймер собьются другие часы", "отвалится коннект к базе данных" или "произойдёт атомный взрыв" не будет - можете посмотреть декомпилированный исходник и глянуть код, этот класс даже не реализует IDisposable
, так что сложностей с пониманием никаких нет.
// Decompiled with JetBrains decompiler
// Type: System.Diagnostics.Stopwatch
// Assembly: System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 988FA076-10C9-4365-AE6D-295A6AA379FE
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll
using Microsoft.Win32;
namespace System.Diagnostics
{
/// <summary>Provides a set of methods and properties that you can use to accurately measure elapsed time.To browse the .NET Framework source code for this type, see the Reference Source.</summary>
[__DynamicallyInvokable]
public class Stopwatch
{
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = 10000000;
private long elapsed;
private long startTimeStamp;
private bool isRunning;
/// <summary>Gets the frequency of the timer as the number of ticks per second. This field is read-only.</summary>
[__DynamicallyInvokable]
public static readonly long Frequency;
/// <summary>Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.</summary>
[__DynamicallyInvokable]
public static readonly bool IsHighResolution;
private static readonly double tickFrequency;
static Stopwatch()
{
if (!SafeNativeMethods.QueryPerformanceFrequency(out Stopwatch.Frequency))
{
Stopwatch.IsHighResolution = false;
Stopwatch.Frequency = 10000000L;
Stopwatch.tickFrequency = 1.0;
}
else
{
Stopwatch.IsHighResolution = true;
Stopwatch.tickFrequency = 10000000.0;
Stopwatch.tickFrequency /= (double) Stopwatch.Frequency;
}
}
/// <summary>Initializes a new instance of the <see cref="T:System.Diagnostics.Stopwatch" /> class.</summary>
[__DynamicallyInvokable]
public Stopwatch()
{
this.Reset();
}
/// <summary>Starts, or resumes, measuring elapsed time for an interval.</summary>
[__DynamicallyInvokable]
public void Start()
{
if (this.isRunning)
return;
this.startTimeStamp = Stopwatch.GetTimestamp();
this.isRunning = true;
}
/// <summary>Initializes a new <see cref="T:System.Diagnostics.Stopwatch" /> instance, sets the elapsed time property to zero, and starts measuring elapsed time.</summary>
/// <returns>A <see cref="T:System.Diagnostics.Stopwatch" /> that has just begun measuring elapsed time.</returns>
[__DynamicallyInvokable]
public static Stopwatch StartNew()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
return stopwatch;
}
/// <summary>Stops measuring elapsed time for an interval.</summary>
[__DynamicallyInvokable]
public void Stop()
{
if (!this.isRunning)
return;
this.elapsed += Stopwatch.GetTimestamp() - this.startTimeStamp;
this.isRunning = false;
if (this.elapsed >= 0L)
return;
this.elapsed = 0L;
}
/// <summary>Stops time interval measurement and resets the elapsed time to zero.</summary>
[__DynamicallyInvokable]
public void Reset()
{
this.elapsed = 0L;
this.isRunning = false;
this.startTimeStamp = 0L;
}
/// <summary>Stops time interval measurement, resets the elapsed time to zero, and starts measuring elapsed time.</summary>
[__DynamicallyInvokable]
public void Restart()
{
this.elapsed = 0L;
this.startTimeStamp = Stopwatch.GetTimestamp();
this.isRunning = true;
}
/// <summary>Gets a value indicating whether the <see cref="T:System.Diagnostics.Stopwatch" /> timer is running.</summary>
/// <returns>
/// <see langword="true" /> if the <see cref="T:System.Diagnostics.Stopwatch" /> instance is currently running and measuring elapsed time for an interval; otherwise, <see langword="false" />.</returns>
[__DynamicallyInvokable]
public bool IsRunning
{
[__DynamicallyInvokable] get
{
return this.isRunning;
}
}
/// <summary>Gets the total elapsed time measured by the current instance.</summary>
/// <returns>A read-only <see cref="T:System.TimeSpan" /> representing the total elapsed time measured by the current instance.</returns>
[__DynamicallyInvokable]
public TimeSpan Elapsed
{
[__DynamicallyInvokable] get
{
return new TimeSpan(this.GetElapsedDateTimeTicks());
}
}
/// <summary>Gets the total elapsed time measured by the current instance, in milliseconds.</summary>
/// <returns>A read-only long integer representing the total number of milliseconds measured by the current instance.</returns>
[__DynamicallyInvokable]
public long ElapsedMilliseconds
{
[__DynamicallyInvokable] get
{
return this.GetElapsedDateTimeTicks() / 10000L;
}
}
/// <summary>Gets the total elapsed time measured by the current instance, in timer ticks.</summary>
/// <returns>A read-only long integer representing the total number of timer ticks measured by the current instance.</returns>
[__DynamicallyInvokable]
public long ElapsedTicks
{
[__DynamicallyInvokable] get
{
return this.GetRawElapsedTicks();
}
}
/// <summary>Gets the current number of ticks in the timer mechanism.</summary>
/// <returns>A long integer representing the tick counter value of the underlying timer mechanism.</returns>
[__DynamicallyInvokable]
public static long GetTimestamp()
{
if (!Stopwatch.IsHighResolution)
return DateTime.UtcNow.Ticks;
long num = 0;
SafeNativeMethods.QueryPerformanceCounter(out num);
return num;
}
private long GetRawElapsedTicks()
{
long elapsed = this.elapsed;
if (this.isRunning)
{
long num = Stopwatch.GetTimestamp() - this.startTimeStamp;
elapsed += num;
}
return elapsed;
}
private long GetElapsedDateTimeTicks()
{
long rawElapsedTicks = this.GetRawElapsedTicks();
if (Stopwatch.IsHighResolution)
return (long) ((double) rawElapsedTicks * Stopwatch.tickFrequency);
return rawElapsedTicks;
}
}
}
PS "Класс Stopwatch появился в .NET 2.0 и с тех по не претерпел ни одного изменения."
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
есть диалоговое окно с Switch и TextView, хочу при переключении Switch отображать или прятать TextViewНиже приведенный код не работает, пробовал на переключение...
Есть Konica Minolta 554e, на ней размножаем документы (всего 38 документов)Часть из документов печатается в две страницы на листе, часть одностраничные,...
У меня есть страница, на которой три поляДанные в контроллер отправляются при помощи Ajax