c#UWP如何安排在当前Dispatcher.ProcessEvents()之后运行的内容?有可能吗?

c#UWP如何安排在当前Dispatcher.ProcessEvents()之后运行的内容?有可能吗?,c#,uwp,win-universal-app,C#,Uwp,Win Universal App,我正在尝试创建一个非常简单的“游戏引擎”,在通用平台和Win2D中玩 我想创建一个可以启动和停止的“主游戏循环” public async void StartGameLoop() { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { GameLoopStopSignal = false;

我正在尝试创建一个非常简单的“游戏引擎”,在通用平台和Win2D中玩

我想创建一个可以启动和停止的“主游戏循环”

public async void StartGameLoop()
{           
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
    {
        GameLoopStopSignal = false;
        while (!GameLoopStopSignal)
        {
            //something like good old DoEvents()?
            CoreApplication.MainView.CoreWindow.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

            //Game Tick
            Tick();
        }
    });
}
public void StopGameLoop()
{
    GameLoopStopSignal = true;
}
如果我在某个页面的“已加载”事件中调用StartGameLoop(),一切都会像一个符咒一样工作

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    StartGameLoop();//all good
}
但如果我在按钮的“click”事件中调用StartGameLoop(),我会得到一个灾难性的失败异常,声明“不允许嵌套调用ProcessEvents方法”。witch实际上是有道理的

private void Button_Click(object sender, RoutedEventArgs e)
{
    StartGameLoop();//will cause exception on Dispatcher.ProcessEvents()
}
因此,我正在寻找一种方法,以确保当我单击这些UI按钮时,在任何可能正在运行的ProcessEvents()调用之后游戏循环开始。。我还没有什么想法:)

谢谢您的帮助。

尝试
等待任务。Yield()

这会告诉调度器在完成处理时,在成品后处理任何内容。这不是保证。。。调度员决定什么是优先级,但是试一下,看看它是否是您需要的

举个例子,试试这个:

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, async () =>
{
    GameLoopStopSignal = false;
    while (!GameLoopStopSignal)
    {
        //something like good old DoEvents()?
        CoreApplication.MainView.CoreWindow.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

        await Task.Yield();
        //Game Tick
        Tick();
    }
});

注意
RunAsync
方法中的
async()=>{…}

最后我恢复使用Task.Run()(因此在线程池中运行主循环),而不是在CoreWindow.Dispatcher(在主UI线程中)上运行;似乎绕过了我所有的问题。不确定它最后是否会回来咬我,但我祈祷

public void StartGameLoop()
{           
    Task.Run(() =>
    {
        GameLoopStopSignal = false;
        clock.Start();
        while (!GameLoopStopSignal)
        {
            Tick();
        }
        clock.Stop();
    });
}

非常感谢。我会在下班后尝试这个方法,并让您知道这是一个非常好的主意,但不幸的是,这并没有改变我所能看到的任何东西。不过,我开始觉得我不需要Dispatcher.ProcessEvent()调用。。感谢您的提示,我不知道task yieldingOK,因此对于记录,task.Yield()调用基本上是在对Dispatcher.ProcessEvent()执行我想要执行的操作,这使系统有机会在进入另一个Tick()之前处理输入/事件。请不要说,
DoEvents
曾经是“好老”——事实并非如此
DoEvents
是一件可怕的事情。