diff --git a/Source/AssemblyInfo.cs b/Source/AssemblyInfo.cs
index c83e8ca..6cb920c 100644
--- a/Source/AssemblyInfo.cs
+++ b/Source/AssemblyInfo.cs
@@ -5,5 +5,5 @@ using System.Reflection;
[assembly: AssemblyCompany("MS Open Tech")]
[assembly: AssemblyProduct("Tx (LINQ to Logs and Traces)")]
[assembly: AssemblyCopyright("Copyright © MS Open Tech 2012")]
-[assembly: AssemblyVersion("1.0.50917.0")]
-[assembly: AssemblyFileVersion("1.0.50917.0")]
\ No newline at end of file
+[assembly: AssemblyVersion("1.0.50930.0")]
+[assembly: AssemblyFileVersion("1.0.50930.0")]
\ No newline at end of file
diff --git a/Source/Tx.Windows/EtwNative/EtwNativeEvent.cs b/Source/Tx.Windows/EtwNative/EtwNativeEvent.cs
index 837bd86..988b9e8 100644
--- a/Source/Tx.Windows/EtwNative/EtwNativeEvent.cs
+++ b/Source/Tx.Windows/EtwNative/EtwNativeEvent.cs
@@ -64,7 +64,7 @@ namespace Tx.Windows
public DateTimeOffset TimeStamp
{
- get { return DateTime.FromFileTimeUtc(record->EventHeader.TimeStamp); }
+ get { return TimeUtil.DateTimeOffsetFromFileTime(record->EventHeader.TimeStamp); }
}
public Int64 TimeStampRaw
diff --git a/Source/Tx.Windows/PerfCounters/PerfCounterFileReader.cs b/Source/Tx.Windows/PerfCounters/PerfCounterFileReader.cs
index 9627119..023c8e8 100644
--- a/Source/Tx.Windows/PerfCounters/PerfCounterFileReader.cs
+++ b/Source/Tx.Windows/PerfCounters/PerfCounterFileReader.cs
@@ -55,7 +55,7 @@ namespace Tx.Windows
break;
PdhUtils.CheckStatus(status, PdhStatus.PDH_CSTATUS_VALID_DATA);
- DateTime timestamp = DateTime.FromFileTimeUtc(time);
+ DateTime timestamp = TimeUtil.FromFileTime(time);
foreach (PerfCounterInfo counterInfo in _counters)
{
diff --git a/Source/Tx.Windows/PerfCounters/PerfCounterRealTimeProbe.cs b/Source/Tx.Windows/PerfCounters/PerfCounterRealTimeProbe.cs
index d626b13..8621e43 100644
--- a/Source/Tx.Windows/PerfCounters/PerfCounterRealTimeProbe.cs
+++ b/Source/Tx.Windows/PerfCounters/PerfCounterRealTimeProbe.cs
@@ -40,7 +40,7 @@ namespace Tx.Windows
long time;
PdhStatus status = PdhNativeMethods.PdhCollectQueryDataWithTime(_query, out time);
PdhUtils.CheckStatus(status, PdhStatus.PDH_CSTATUS_VALID_DATA);
- DateTime timestamp = DateTime.FromFileTimeUtc(time);
+ DateTime timestamp = TimeUtil.FromFileTime(time);
foreach (PerfCounterInfo counterInfo in _counters)
{
diff --git a/Source/Tx.Windows/TimeUtil.cs b/Source/Tx.Windows/TimeUtil.cs
new file mode 100644
index 0000000..3e7f109
--- /dev/null
+++ b/Source/Tx.Windows/TimeUtil.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System;
+
+namespace Tx.Windows
+{
+ public sealed class TimeUtil
+ {
+ private const Int64 TicksPerMillisecond = 10000;
+ private const Int64 TicksPerSecond = TicksPerMillisecond * 1000;
+ private const Int64 TicksPerMinute = TicksPerSecond * 60;
+ private const Int64 TicksPerHour = TicksPerMinute * 60;
+ private const Int64 TicksPerDay = TicksPerHour * 24;
+
+ // Number of days in a non-leap year
+ private const int DaysPerYear = 365;
+ // Number of days in 4 years
+ const int DaysPer4Years = DaysPerYear * 4 + 1;
+ // Number of days in 100 years
+ private const int DaysPer100Years = DaysPer4Years * 25 - 1;
+ // Number of days in 400 years
+ private const int DaysPer400Years = DaysPer100Years * 4 + 1;
+
+ // Number of days from 1/1/0001 to 12/31/1600
+ private const int DaysTo1601 = DaysPer400Years * 4;
+
+ private const Int64 FileTimeOffset = DaysTo1601 * TicksPerDay;
+
+ public static DateTimeOffset DateTimeOffsetFromFileTime(Int64 fileTime)
+ {
+ return new DateTimeOffset(FileTimeOffset + fileTime, TimeSpan.Zero);
+ }
+
+ public static DateTime FromFileTime(Int64 fileTime)
+ {
+ return new DateTime(FileTimeOffset + fileTime, DateTimeKind.Local);
+ }
+ }
+}
+
diff --git a/Source/Tx.Windows/Tx.Windows.csproj b/Source/Tx.Windows/Tx.Windows.csproj
index ca1b85d..0dc44c9 100644
--- a/Source/Tx.Windows/Tx.Windows.csproj
+++ b/Source/Tx.Windows/Tx.Windows.csproj
@@ -87,6 +87,7 @@
+
diff --git a/Test/UnitTests/PerfCounterTest.cs b/Test/UnitTests/PerfCounterTest.cs
index 96d36bd..158de1e 100644
--- a/Test/UnitTests/PerfCounterTest.cs
+++ b/Test/UnitTests/PerfCounterTest.cs
@@ -10,6 +10,8 @@ using Tx.Windows;
namespace Tests.Tx
{
+ using System.Globalization;
+
[TestClass]
public class PerfCounterTest
{
@@ -140,6 +142,39 @@ namespace Tests.Tx
Assert.AreEqual(600, disk.Count());
}
+ [TestMethod]
+ public void PerformanceCounterProbeFirst()
+ {
+ PerformanceSample[] result;
+ var startTime = DateTimeOffset.UtcNow;
+
+ using (var playback = new Playback())
+ {
+ ((IPlaybackConfiguration)playback).AddInput(
+ () => PerfCounterObservable.FromRealTime(TimeSpan.FromSeconds(1), @"\Processor(_Total)\% User Time").Take(1),
+ typeof(PerfCounterPartitionTypeMap),
+ typeof(PerfCounterTypeMap));
+
+ var query = playback.GetObservable();
+
+ var enumerable = playback.BufferOutput(query);
+
+ playback.Run();
+
+ result = enumerable.ToArray();
+ }
+ var endTime = DateTimeOffset.UtcNow;
+
+ Assert.AreEqual(1, result.Length);
+
+ Assert.AreEqual("% User Time", result[0].CounterName, false, CultureInfo.InvariantCulture);
+ Assert.AreEqual("Processor", result[0].CounterSet, false, CultureInfo.InvariantCulture);
+ Assert.AreEqual("_Total", result[0].Instance, false, CultureInfo.InvariantCulture);
+ var dto = new DateTimeOffset(result[0].Timestamp);
+ Assert.IsTrue(dto >= startTime);
+ Assert.IsTrue(dto <= endTime);
+ }
+
IEnumerable PivotToInstanceSnapshots(Playback playback, string counterSet)
{
var all = playback.GetObservable();