运行C#任务将冻结WPF UI

时间:2019-01-29 22:42:09

标签: c# wpf asynchronous

我想用C#/ WPF构建一个扑克应用程序。 CPU播放器轮到他们了,但是当用户需要采取行动时,我遇到了问题,因为我想等待播放器的输入,但是我的循环冻结了UI。 代码如下:

public override async void TakeTurn()
{
        await WaitForUserInput();
}

private async Task<int> WaitForUserInput()
{
    await Task.Run((() => WaitForUserInput2()));
    return 42;
}

private void WaitForUserInput2()
{
    while (BetsFinished == false || Game.PlayersRound.Contains(this))
    {
        //Loop that gets broken by user interaction
    }
}

我运行的任务会被用户输入打断(单击按钮会将BetsFinished设置为true),这是不可能的,因为一旦调用TakeTurn就会冻结UI。该代码位于Model类中,因此如果有关系,它与View没有直接连接。用户交互将通过绑定到命令的按钮进行。

从我的Poker类中调用TakeTurn()方法,该方法定义了游戏流程。

我尝试了多种设置(例如,在WaitForUserInput()前面没有等待),但是没有成功。

所以我的目标是让此循环运行而不会冻结UI。

1 个答案:

答案 0 :(得分:2)

UI应用程序与控制台应用程序非常不同。在UI应用程序中,无论输入是什么,您都应该构建逻辑以对用户输入进行反应。换句话说,您应该使用WaitForUserInput方法;该方法的存在表明您的程序正在尝试驱动用户,而不是用户在驱动程序。

相反,您应该将游戏状态保留在内存中,并且当用户单击Bid按钮(或其他按钮)时,通过移至新状态来对该用户输入进行反应 。限制用户的选择是很好的-例如,如果您想在计算机播放器移动时禁用用户按钮。但是,(错误地)使用asyncawait来编码预期的交互逻辑正在给世界带来痛苦。

P.S。对于WPF扑克游戏,我看不到任何I / O,因此最终应用程序中可能根本没有asyncawait