0

我正在尝试在 C# 和 Unity 中使用 、 和 s 来async解决await问题。Task这是场景:

  1. 用户单击按钮。
  2. 它的脚本(例如MyScene.ButtonOnClick():)生成一个(自定义)对话框并输入等待用户响应的模式。
  3. 然后用户enum DBResponse { Yes, No, Cancel }通过单击三个按钮之一从三个选项(例如:)中进行选择。
  4. 结果返回到原始按钮单击后面的脚本。
  5. 原始脚本使用响应继续执行代码。

似乎async, await, and Task<TResult>(即“基于任务的异步模式”或 TAP)将是这个问题的现代答案,而不是使用事件和侦听器或 Unity 的协程,但我能找到的唯一例子与计算昂贵的例程或读/写有关,而不是与用户输入有关。

我在这里尝试使用错误的工具吗?如果没有,那么我可以在三个按钮的 OnClick() 方法中添加什么来让用户对原始脚本的响应?我正在努力标记一个正在进行中的异步,即有一个更新并且它已经完全可以继续进行(这听起来很像监听一个事件,这对我来说也是一个弱点)。

在早期,我会使用静态事件管理器和一系列侦听器和调用器作为触发器。最近,我使用了一个协程,但因为它没有返回值,所以我将响应存储为一个公共静态值,这似乎非常错误。

这似乎是一个如此简单而根本的问题,但我还没有能够破解它。我有一种感觉,如果这Task正确的工具,那么我缺少 ' 方法和属性的一些基本用法。

指向额外阅读的指针将非常有帮助!

4

1 回答 1

-2

似乎 async、await 和 Task(即“基于任务的异步模式”或 TAP )将是这个问题的现代答案

这是在骗你。虽然看起来这将是一个很好的用例,但事实并非如此。使用 async/await 模式的主要优点是将通常等待 IO 结果(网络、硬盘驱动器等)的线程返回到可用于其他任务。这不是那种情况。

我强烈建议观看 Lucian Wischik 包装事件以公开 async/await

Lucian Wischik 曾经/现在在 Microsoft 的 VB/C# 语言设计团队工作,并且在发布时是 Microsoft 在 async/await 方面知识最渊博的人之一。

所以这是一个非常粗略的例子,说明如何包装事件以供等待消费。看完之后,你可以决定它是否更容易阅读和更容易维护,而不是直接使用事件。

public async Task<DBResponse> ShowDialogAsync() 
{
  var tcs = new TaskCompletionSource<DBResponse>();
  EventHandler<object> lamda = (s,e) => tsc.TrySetResult(MyDialog.Result);

  try 
  {
    MyDialog.OnClose += lambda;
    MyDialog.Show();
    var result = await tcs.Task;
    return result;
  }
  finally
  {
    MyDialog.OnClose += lambda;
  }
}

所以要绝对清楚,这并没有像您在问题中建议的那样提供替代方案,因为它仍在使用事件。

似乎 async、await 和 Task(即“基于任务的异步模式”或 TAP )将是这个问题的现代答案,而不是使用事件

于 2021-06-11T23:12:26.097 回答