【问题标题】:How to wait in main UI thread for user interaction without blocking it?如何在主 UI 线程中等待用户交互而不阻塞它?
【发布时间】:2016-11-21 18:25:32
【问题描述】:

假设我有一个在主 UI 线程上运行的实例方法,将自定义 UserControl (WPF) 添加到可通过单例访问的主应用程序窗口,然后需要等待进一步执行直到用户与该UserControl 交互并返回一些值。

我的第一次尝试总是会阻塞 UI 线程,因此用户实际上无法与UserControl 进行交互,直到我最终遇到asyncawait

以下是我提出的解决方案的简化要点:

Public Class ControlManagerA
    Inherits ControlManagerBase

    Public Property userControlResult As String

    Public Overrides Async Function CreateAndWait() As Task

        'Initialize to some default value to indicate that no response was received yet.
        userControlResult = Nothing

        Dim myCustomControl As New MyCustomUserControlA()
        'Could also pass any additional parameters required for display.
        myCustomControl.AssignParent(Me)

        GlobalUIManager.GetMainWindow().AssignUserControl(myCustomControl)

        'This will eventually be populated with a proper value due to
        'user interaction in MyCustomUserControlA.
        While userControlResult Is Nothing
            'This is the part that I am a little unhappy about.
            Await Task.Delay(1)
        End While

        GlobalUIManager.GetMainWindow().RemoveUserControl(myCustomControl)

        DoSomethingWithResult(userControlResult)

    End Function
End Class

让我烦恼的一件事是我正忙着在那里循环等待。 (事实上​​我也可以将userControlResult 作为ByRef 参数传递,而不是等待MyCustomUserControlA 通过公共属性访问它。) 该解决方案仍在为我工作,我根本没有注意到任何性能问题,但我想知道是否有更好的方法在这里等待结果。我也不知道Task.Delay(1) 是浪费还是在开销方面实际上是相当轻量级的。

【问题讨论】:

  • 似乎从MyCustomUserControlA 引发由ControlManagerA(或其他一些回调机制)处理的事件会减少耦合并简化事情,但也许我不了解整个情况?
  • 代码流需要在那个特定的方法中继续,这就是为什么我需要在那里等待。我无法在稍后的某个时间点继续进行会启动单独流程的事件(至少在不等待该事件的情况下不会)。

标签: .net wpf vb.net asynchronous


【解决方案1】:

虽然您可以 await UI things such as button clicks,但这样做是有问题的。如果用户做了其他事情,比如关闭那个窗口怎么办?或者点击其他地方?

最好设计一个不会将用户限制在单个 UI 工作流程中的 UX。

【讨论】:

  • 应用程序是一个游戏,因此没有实际的“工作流程指南”可以遵循。对于玩家来说,弹出和关闭多个窗口实际上会很麻烦(这是我过去所拥有的 - 这实际上是一种摆脱这种设计的尝试)。如果此 UserControl 发挥作用,则唯一可点击的东西实际上是 UserControl 中的内容,尽管 UI 的其他部分可能仍然可见。关闭该窗口意味着退出游戏。 (是的,我知道 WPF 可能不是 .NET 中最适合游戏的东西,但我还是在滥用它 :))
  • 再一次,你的链接让我知道TaskCompletionSource,它似乎正在做我需要的事情。我会试一试,看看它是否适用于我的场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多