2011-01-16 4 views
2

Ich frage mich, was ist der sicherste Weg, um zwei System.Runtime.InteropServices.ComTypes.FILETIME Objekte zu subtrahieren? Ich habe den folgenden Code verwendet, aber manchmal gibt es mir ArithmaticOverflow Ausnahme aufgrund der negativen Zahl in niedrigen 32-Bit-Werten. Ich bin mir nicht sicher, ob die Umhüllung des Körpers mit unchecked dem Zweck dient oder nicht. Bitte geben Sie mir einen Vorschlag, wie Sie das sicher tun können, ohne eine Laufzeitausnahme oder eine CS0675-Warnmeldung zu erhalten.Was ist der sicherste Weg, um zwei System.Runtime.InteropServices.ComTypes.FILETIME Objekte zu subtrahieren

private static UInt64 SubtractTimes(FILETIME a, FILETIME b) 
     { 
      UInt64 aInt = ((UInt64)(a.dwHighDateTime << 32)) | (UInt32)a.dwLowDateTime; 
      UInt64 bInt = ((UInt64)(b.dwHighDateTime << 32)) | (UInt32)b.dwLowDateTime; 
      return aInt - bInt; 
     } 

Antwort

1

Sie müssen ungeprüft verwenden, um die Ausnahme zu unterdrücken:

public static long FileTime2Long(FILETIME ft) { 
     uint low = unchecked((uint)ft.dwLowDateTime); 
     return (long)ft.dwHighDateTime << 32 | low; 
    } 

    static void Test() { 
     FILETIME ft = new FILETIME(); 
     ft.dwHighDateTime = 1; 
     ft.dwLowDateTime = -1; 
     long value = FileTime2Long(ft); 
     Debug.Assert(value == 0x1ffffffff); 
    } 

Falls gewünscht, können Sie dann auf Datetime mit DateTime.FromFileTimeUtc() konvertieren.

0

Sie können mithilfe DateTime.FromFileTime() Methode FILE zu Datetime-Objekt konvertieren und dann können Sie sicher subtrahieren Datetime-Objekte.

Wenn Sie das gleiche Problem haben, verwenden Sie die unten stehende Methode, da DateTime.FromFileTime() nicht immer funktioniert, dank signierter/unsignierter Probleme.

public static DateTime ToDateTime(System.Runtime.InteropServices.FILETIME ft) 
{ 
    IntPtr buf = IntPtr.Zero; 
    try 
    { 
    long[] longArray = new long[1]; 
    int cb = Marshal.SizeOf(ft); 
    buf = Marshal.AllocHGlobal(cb); 
    Marshal.StructureToPtr(ft, buf, false); 
    Marshal.Copy(buf, longArray, 0, 1); 
    return DateTime.FromFileTime(longArray[0]); 
    } 
    finally 
    { 
    if (buf != IntPtr.Zero) Marshal.FreeHGlobal(buf); 
    } 
}