DateTimeOffset :: Now继续在进程暂停和恢复后停止的位置

时间:2017-09-24 18:38:33

标签: c# powershell time

我有一个PowerShell脚本,它返回特定PID的内存使用情况,示例输出:

...
1506277002989 (*nix TS) - Pid:11640 - 263.47 M
1506277003010 (*nix TS) - Pid:11640 - 263.47 M
1506277003033 (*nix TS) - Pid:11640 - 263.47 M
... // output continues

如果我暂停PowerShell进程监视PID两秒钟然后再继续它,则时间戳会变得不正确,转移到过去。

在我的PowerShell脚本中,我使用此函数来抽样时间:

while (1) {
    $date = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()
    Write-Host -NoNewline "$date (*nix TS) - "
    ... # script continues

这是我用来暂停和恢复过程的代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace ProcessSuspendAndCtd
{
    class Program
    {

        static void Main(string[] args)
        {
            int pid = Int32.Parse(args[0]);
            SuspendProcess(pid);
            Task.Delay(5000).Wait();
            ResumeProcess(pid);
        }

        [Flags]
        private enum ThreadAccess : int
        {
            TERMINATE = (0x0001),
            SUSPEND_RESUME = (0x0002),
            GET_CONTEXT = (0x0008),
            SET_CONTEXT = (0x0010),
            SET_INFORMATION = (0x0020),
            QUERY_INFORMATION = (0x0040),
            SET_THREAD_TOKEN = (0x0080),
            IMPERSONATE = (0x0100),
            DIRECT_IMPERSONATION = (0x0200)
        }

        [DllImport("kernel32.dll")]
        static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
        [DllImport("kernel32.dll")]
        static extern uint SuspendThread(IntPtr hThread);
        [DllImport("kernel32.dll")]
        static extern int ResumeThread(IntPtr hThread);
        [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool CloseHandle(IntPtr handle);


        internal static void SuspendProcess(int pid)
        {
            var process = Process.GetProcessById(pid);

            if (process.ProcessName == string.Empty)
                return;

            foreach (ProcessThread pT in process.Threads)
            {
                IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);

                if (pOpenThread == IntPtr.Zero)
                {
                    continue;
                }

                SuspendThread(pOpenThread);

                CloseHandle(pOpenThread);
            }
        }

        internal static void ResumeProcess(int pid)
        {
            var process = Process.GetProcessById(pid);

            if (process.ProcessName == string.Empty)
                return;

            foreach (ProcessThread pT in process.Threads)
            {
                IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);

                if (pOpenThread == IntPtr.Zero)
                {
                    continue;
                }

                var suspendCount = 0;
                do
                {
                    suspendCount = ResumeThread(pOpenThread);
                } while (suspendCount > 0);

                CloseHandle(pOpenThread);
            }
        }
    }
}

问题:如果我再次调用函数,为什么时钟会变得不同步?是因为它只在初始化期间与系统时间同步吗?我应该如何以最一般的方式解决它?

0 个答案:

没有答案