C# Unity中UI的异步/等待样式

C# Unity中UI的异步/等待样式,c#,unity3d,async-await,C#,Unity3d,Async Await,我想在UnityforUI中实现异步/等待样式。我突然想到,您可以编写一个静态类,在其中定义这样的方法公共静态异步任务WaitForButtonClickAsync(CancellationToken ct,params Button[]buttons)此方法将等待使用任务按下任何传输的按钮。当任何按钮按下时,它将返回一个按钮。那之后呢?我只能想出一个巨大的开关盒块来确定按下了哪个按钮,或者立即通过回调方法传递按钮,但在我看来,这些并不是最好的解决方案。我非常成功地使用了这种模式。但是你对这个巨

我想在UnityforUI中实现异步/等待样式。我突然想到,您可以编写一个静态类,在其中定义这样的方法
公共静态异步任务WaitForButtonClickAsync(CancellationToken ct,params Button[]buttons)
此方法将等待使用
任务按下任何传输的按钮。当任何按钮按下时,它将返回一个按钮。那之后呢?我只能想出一个巨大的
开关盒
块来确定按下了哪个按钮,或者立即通过回调方法传递按钮,但在我看来,这些并不是最好的解决方案。

我非常成功地使用了这种模式。但是你对这个巨大的开关箱的看法是对的,它确实需要一些样板。但话说回来,回调实际上并不短

例如:

Button pressedButton = await WaitForButtonClickAsync(ct, button1, button2, button3);
if (pressedButton == button1) await DoStuff1(ct);    
if (pressedButton == button2) await DoStuff2(ct);
if (pressedButton == button3) await DoStuff3(ct);
或者使用回调(请注意,我们并没有在这里删除事件处理程序,所以这个解决方案实际上并不短),尽管在这里我们没有得到链接异步代码的优势:

button1.onClick += () => DoStuff1();
button2.onClick += () => DoStuff2();
button3.onClick += () => DoStuff3();
你也可以做一些帮助来避免if-Else,比如:

await WaitForButtonHandlersAsync(ct, 
                                (button1, DoStuff1), 
                                (button2, DoStuff2),
                                (button3, DoStuff3));
但当你开始在按钮之外加入其他等待时,这可能会变得混乱,我总是回到if-else列表

编辑: 广告的一个特点是,你也可以把东西分组。例如,如果除了一些特定于上下文的按钮外,还有一组常用的导航按钮/手势,则可以将导航按钮捆绑到一个任务中。此示例还包含视频中显示的链接令牌的用法

using (var cts = CreateLinkedTokenSource(ct))
{
    var navigationTask = WaitForNavigationEventAsync(cts.Token);
    var buttonTask1 = WaitForButtonClickAsync(cts.Token, button1);
    var buttonTask2 = WaitForButtonClickAsync(cts.Token, button2);

    var finishedTask = await Task.WhenAny(navigationTask, buttonTask1, buttonTask2);
    await finishedTask; // "Reveal" and propagate exceptions
    cts.Cancel();

    if (finishedTask == navigationTask) await Navigate(navigationTask.Result, ct);
    if (finishedTask == buttonTask1) await DoStuff1(ct);
    if (finishedTask == buttonTask2) await DoStuff2(ct);
}

使用这种构造,列表永远不会失控,您可以避免一些重复的代码。

这到底有什么用处?你可以看几分钟这段视频(36:00开始)。演讲者谈论这个模式解决的用户界面问题。哇,这个话题真的很有趣。。但是我仍然不明白为什么你会对这样的弹出窗口使用例程或异步^^^我们所做的就是在开始时简单地向它传递一些回调侦听器,以便稍后我们也知道这个弹出窗口是否被接受、取消、关闭或某个地方失败。。。我真的不认为有必要在这种情况下使用这样的模式,但发言人说,这将有助于解决双击按钮的问题,一次按下两个按钮,按下这个弹出屏幕后面的按钮,甚至不用考虑,只使用这种模式。我觉得这会很方便。为什么不呢?我使用的方法如下
异步任务WaitForButtons单击async(CancellationToken ct,params[]Buttons)
。如果对场景中的所有按钮使用此方法,前提是每次新调用时,旧方法将使用令牌关闭,那么当我调用此类弹出窗口时,我将只将此窗口中的按钮传递给此方法,因此场景中的任何其他按钮都不会执行任何操作,直到按下其中一个传递的按钮并使用其他参数调用此方法。当我点击第一个按钮并返回它时。