Какой самый безопасный способ вычесть два объекта System.Runtime.InteropServices.ComTypes.FILETIME - PullRequest
2 голосов
/ 16 января 2011

Интересно, какой самый безопасный способ вычесть два System.Runtime.InteropServices.ComTypes.FILETIME объекта?Я использовал следующий код, но иногда он дает мне исключение ArithmaticOverflow из-за отрицательного числа в младших 32-битных значениях.Я не уверен, что включение тела с unchecked послужит цели или нет.Пожалуйста, дайте мне несколько советов о том, как сделать это безопасно, без каких-либо исключений во время выполнения или предупреждающего сообщения CS0675.

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;
        }

Ответы [ 2 ]

1 голос
/ 16 января 2011

Вам нужно использовать без проверки , чтобы подавить исключение:

    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);
    }

При желании вы можете затем преобразовать в DateTime с DateTime.FromFileTimeUtc ().

0 голосов
/ 16 января 2011

Вы можете преобразовать FILETIME в объект DateTime с помощью метода DateTime.FromFileTime () , а затем вы можете безопасно вычесть объекты DateTime.

Если у вас возникнет та же проблема, используйте метод ниже, потому что DateTime.FromFileTime () работает не во всех случаях из-за проблем со знаком / без знака.

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 );
  }
}
...