Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查用户在UWP上是否空闲?_C#_Timer_Uwp - Fatal编程技术网

C# 如何检查用户在UWP上是否空闲?

C# 如何检查用户在UWP上是否空闲?,c#,timer,uwp,C#,Timer,Uwp,我想做一个函数,如果用户空闲一段时间,该函数将超时并导航到主页。经过一点研究,我发现ThreadPoolTimer应该适合我的需要。测试它时,我决定使用10秒的间隔 timer =ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,TimeSpan.FromSeconds(10)); 而这正是我不知所措的地方。我想不出一种方法来检查UWP上的用户输入,而不必单独检查PointerPressed、PointerExit等。所以我做了更多的挖掘,发

我想做一个函数,如果用户空闲一段时间,该函数将超时并导航到主页。经过一点研究,我发现ThreadPoolTimer应该适合我的需要。测试它时,我决定使用10秒的间隔

    timer =ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,TimeSpan.FromSeconds(10));
而这正是我不知所措的地方。我想不出一种方法来检查UWP上的用户输入,而不必单独检查PointerPressed、PointerExit等。所以我做了更多的挖掘,发现了一段代码,如果用户空闲或不空闲,它应该给你一个布尔值

    public static uint GetIdleTime()
    {
        LASTINPUTINFO lastInPut = new LASTINPUTINFO();
        lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
        GetLastInputInfo(ref lastInPut);

        return ((uint)Environment.TickCount - lastInPut.dwTime);
    }

    public static bool IsUserIdle()
    {
        uint idleTime = (uint)Environment.TickCount - GetLastInputEventTickCount();
       if (idleTime > 0)
       {
           idleTime = (idleTime / 1000);
       }
       else
       {
           idleTime = 0;
       }
       //user is idle for 10 sec
       bool b = (idleTime >= 10);
       return b;
    }

    private static uint GetLastInputEventTickCount()
    {
        LASTINPUTINFO lii = new LASTINPUTINFO();
        lii.cbSize = (uint)Marshal.SizeOf(lii);
        lii.dwTime = 0;
        uint p = GetLastInputInfo(ref lii) ? lii.dwTime : 0;
        return p;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct LASTINPUTINFO
    {
        public static readonly int SizeOf = Marshal.SizeOf<LASTINPUTINFO>();
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 cbSize;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 dwTime;
    }

    [DllImport("user32.dll")]
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
但是当我启动它时,什么都没有发生,在我设置了几个断点之后,我发现IsUserIdle()即使在不活动10秒后也不会返回真值。我完全陷入困境,因此任何帮助都将不胜感激

Windows应用商店应用程序不支持:

支持的最低客户端:Windows 2000 Professional[仅限桌面应用程序]

我不知道有任何内在的uwpapi可以检测用户是否空闲,但完全有可能启动自己的机制来检测用户是否空闲

我无法找到一种方法来检查UWP上的用户输入,而不必单独检查PointerPressed、PointerExit等

这种方法有什么不好?以下是我的尝试:

App.xaml.cs

public sealed partial class App : Application
{
    public static new App Current => (App)Application.Current;

    public event EventHandler IsIdleChanged;

    private DispatcherTimer idleTimer;

    private bool isIdle;
    public bool IsIdle
    {
        get
        {
            return isIdle;
        }

        private set
        {
            if (isIdle != value)
            {
                isIdle = value;
                IsIdleChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        idleTimer = new DispatcherTimer();
        idleTimer.Interval = TimeSpan.FromSeconds(10);  // 10s idle delay
        idleTimer.Tick += onIdleTimerTick;
        Window.Current.CoreWindow.PointerMoved += onCoreWindowPointerMoved;
    }

    private void onIdleTimerTick(object sender, object e)
    {
        idleTimer.Stop();
        IsIdle = true;
    }

    private void onCoreWindowPointerMoved(CoreWindow sender, PointerEventArgs args)
    {
        idleTimer.Stop();
        idleTimer.Start();
        IsIdle = false;
    }
}
public sealed partial class MainPage : Page
{
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged += onIsIdleChanged;
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged -= onIsIdleChanged;
    }

    private void onIsIdleChanged(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"IsIdle: {App.Current.IsIdle}");
    }
}
MainPage.xaml.cs

public sealed partial class App : Application
{
    public static new App Current => (App)Application.Current;

    public event EventHandler IsIdleChanged;

    private DispatcherTimer idleTimer;

    private bool isIdle;
    public bool IsIdle
    {
        get
        {
            return isIdle;
        }

        private set
        {
            if (isIdle != value)
            {
                isIdle = value;
                IsIdleChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        idleTimer = new DispatcherTimer();
        idleTimer.Interval = TimeSpan.FromSeconds(10);  // 10s idle delay
        idleTimer.Tick += onIdleTimerTick;
        Window.Current.CoreWindow.PointerMoved += onCoreWindowPointerMoved;
    }

    private void onIdleTimerTick(object sender, object e)
    {
        idleTimer.Stop();
        IsIdle = true;
    }

    private void onCoreWindowPointerMoved(CoreWindow sender, PointerEventArgs args)
    {
        idleTimer.Stop();
        idleTimer.Start();
        IsIdle = false;
    }
}
public sealed partial class MainPage : Page
{
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged += onIsIdleChanged;
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged -= onIsIdleChanged;
    }

    private void onIsIdleChanged(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"IsIdle: {App.Current.IsIdle}");
    }
}

当指针在应用程序窗口内10秒未移动时,检测到空闲。这也适用于纯触摸应用程序(如移动应用程序),因为点击窗口时,PointerMoved也会启动。

对不起,我打字太快了。原始代码应该是bool b=(idleTime>=10)@重力“这种方法有什么不好的地方?”——简言之:它不起作用。它只能记录调用进程的输入事件。而且它不区分用户输入和自动化结果的事件。这种方法会产生误报和误报,当然也无法确定用户是否空闲。不幸的是,没有其他选择(我知道)。对于大多数情况,这已经足够了。这可能足够,也可能不够。但是,读者需要知道,这种实现与基于
GetLastInputInfo
的解决方案在何处以及如何不同。从目前的情况来看,这个答案中甚至没有暗示任何区别。实际上,我已经通过使用dispatcher timer和tick函数而不是threadpool timer修复了我的初始问题。当我调试时,它工作得很好,但现在当我尝试在发布模式下运行它时,我得到一个System.TypeLoad异常,表示未解析的P/Invoke方法“GetLastInputInfo!”!user32.dll在程序集中,因为它在UWP应用程序中不可用。请使用另一个API,或使用[DllImport(ExactSpelling=true)表示您了解使用非UWP应用程序API的含义。@IInspectablereporting。建议的答案在UWP windows IOT.Up上非常稳定。