.net 如何在主UI线程中等待用户交互而不阻塞它?

.net 如何在主UI线程中等待用户交互而不阻塞它?,.net,wpf,vb.net,asynchronous,.net,Wpf,Vb.net,Asynchronous,假设我有一个在主UI线程上运行的实例方法,在主应用程序窗口中添加一个自定义的UserControl(WPF),该窗口可以通过单例访问,然后需要等待进一步执行,直到用户与该UserControl交互并返回一些值 我的第一次尝试总是会阻塞UI线程,因此用户实际上无法与UserControl交互,直到我最终遇到async和wait 以下是我提出的解决方案的简化要点: Public Class ControlManagerA Inherits ControlManagerBase Pu

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

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

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

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)是否浪费资源,或者它实际上在开销方面是否很轻。

尽管可以,但这样做是有问题的。如果用户做了其他事情,比如关闭窗口,该怎么办?或者点击其他地方


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

似乎从
MyCustomUserControlA
引发一个事件,由
ControlManagerA
(或其他回调机制)处理,可以减少耦合并简化事情,但也许我不了解整个情况?代码流需要在特定方法中继续,这就是为什么我需要在那里等待的原因。我不能在以后的某个时间点继续进行一个会启动一个单独流程的事件(至少不能不等待该事件)。该应用程序是一个游戏,因此没有实际的“工作流指南”可遵循。对于一个玩家来说,如果有多个窗口进出(这就是我过去所做的——这实际上是试图摆脱这种设计),那将是一件麻烦事。如果这个用户控件起作用,唯一可点击的东西实际上就是用户控件中的东西,尽管UI的其他部分可能仍然可见。关闭窗口意味着退出游戏。(是的,我知道WPF可能不是.NET中最适合游戏的东西,但我还是滥用了它:))然后,你的链接再次让我意识到了
TaskCompletionSource
,它似乎在做我需要的事情。我将尝试一下,看看它是否在我的场景中起作用。