так ничего не утечёт?
void Foo()
{
var sw = new Stopwatch();
sw.Start();
}
Здравствуйте, abibok, Вы писали:
A>А почему не Stopwatch.StartNew() ?
Ну, если ориентироваться на сценарий использования, то надо как-то так:
{
}
Здравствуйте, маген, Вы писали:
М>Очень простая штука, по сути Start запоминает текущий Tickcount во внутренней переменной и все.
Не все так просто. TickCount сильно меньшее разрешение имеет. Stopwatch использует QueryPerformanceCounter.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, маген, Вы писали:
М>Ну и что?
И то что твое заявление про TickCount не соответствует действительности. Безотносительно отсутствия возможности утечки.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, UberPsychoSvin, Вы писали:
UPS>так ничего не утечёт?UPS> var sw = new Stopwatch();
UPS> sw.Start();
время утечёт
Здравствуйте, UberPsychoSvin, Вы писали:
UPS>ага, а в инете есть статьи, где защищаются от утечек в стопвотче, оборачивая его IDisposable враппер. Вот я и подумал может там и впрямь что то утекает если его не закрыть.
Я подозреваю, что цель оборачивания Stopwatch-а в Disposable-объекты не в том, чтобы защититься от утечки ресурсов, а чтобы сделать
RAII-based решение, при котором мы автоматом получим вывод результата в консоль при выходе из области видимости. Что-то наподобии
Stopwatch used with idisposable, useful.
Другими словами, чтобы не писать вот так:
var stopwatch = Stopwatch.StartNew();
try
{
// Вызываем измеряемый метод
Foo();
}
finally
{
Console.WriteLine("Foo took {0}ms", stopwatch.EllapsedMilliseconds);
}
Делают класс, который в методе Dispose выводит что-то на экран, в результате можно сделать такое:
using (Watcher.Profile(Stopwatch sw =>
Console.WriteLine("Foo took {0}ms", sw.EllapsedMilliseconds))
{
Foo();
}
Хотя в этом плане, есть мнение, что использовать IDisposable-оболочки не есть правильно. В частности у камрада Липперта в "The C# Programming Language" есть вот такая сноска:
8.13 The using Statement.
Eric Lippert. As the specification explicitly calls out here, the point of a using statement is to ensure the acquisition of and timely disposal of a resource. Typically, this will consist of some unmanaged resource from the operating system, such as a file handle. It is polite to stop using resources as soon as possible; some other program might want to read that file when you're done with it. I recommend against the use of using statement to enforce program invariants. For example, one sometimes sees code like this:
using(new TemporarilyStopReportingErrors() AttemptSomething();
Here TemporarilyStopReportingErrors is a type whose constructor turns off error reporting as a side effect and whose disposal method turns it back on. I consider this (unfortunately widespread) practice to be an abuse of the using statement; a program side effect is not a resource, and causing global side effects in constructors and disposers seems like a bad idea. I would write this code using a try-finally construct instead.
Хотя момент спорный, поскольку в том же
Microsoft Fakes используется именно этот же подход:
// Shims can be used only in a ShimsContext:
using (ShimsContext.Create())
{
// Shim DateTime.Now to return a fixed date:
System.Fakes.ShimDateTime.NowGet =
() => new DateTime(2001, 1, 1);
Assert.That(DateTime.Now.Date.Year, Is.EqualsTo(2001));
Assert.That(DateTime.Now.Date.Day, Is.EqualsTo(1));
Assert.That(DateTime.Now.Date.Day, Is.EqualsTo(1));
}
Но, с другой стороны, сам факт этой ветки говорит о том, что оборачивание в Disposable-объекты чего-то ради побочных эффектов, не связанных с освобождением ресурсов и правда может сбивать читателей с толку. Поэтому есть альтернативные подходы, например, использовать такой себе "локальный Метод Шаблона":
class Watcher
{
public static void Profile(Action profilee, Func<Stopwatch> onComplete)
{
var sw = Stopwatch.StartNew();
try
{
profilee();
}
finally
{
sw.Stop();
onComplete(sw);
}
}
}
Правда использование чутка менее удобное,
Watcher.Profile(() => Foo(), sw => Console.WriteLine("Foo took {0}", sw);
Хотя это дело просто изменить и добавить fluent syntax, чтобы результат выглядел так:
Watcher
.Profile(() => Foo())
.OnComplete(sw => Console.WriteLine("Foo took {0}", sw);
Ну и тут нужно понимать, что потенциально в этом случае мы можем получить целый ворох проблем. Теперь у нас есть анонимные методы и замыкания, и если наш профилируемый метод очень короткий, то накладные расходы на "инфраструктуру" могут существенно исказить точность результатов.
Здравствуйте, SergeyT., Вы писали:
ST>Здравствуйте, UberPsychoSvin, Вы писали:
ST>Делают класс, который в методе Dispose выводит что-то на экран, в результате можно сделать такое:
ST>ST>using (Watcher.Profile(Stopwatch sw =>
ST> Console.WriteLine("Foo took {0}ms", sw.EllapsedMilliseconds))
ST>{
ST> Foo();
ST>}
ST>
Так неудобно же. параметры то нельзя в диспоз передавать, о том что же мы такое обрабатывали.
var lt = new LogTime()
lt.Start();
lt.Stop("айтем с айдишником таким то в таких то количествах был обработан за стока то времени");