Как самый безопасный способ вычесть два system.runtime.interopservices.comtypes.filetime объекты
-
11-10-2019 - |
Вопрос
Интересно, какой самый безопасный способ вычесть два 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;
}
Решение
Вам нужно использовать неконтролировано Чтобы подавить исключение:
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 ().
Другие советы
Вы можете преобразовать 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 );
}
}