异步工作流程和用户互动:如何实现“后退”工作。功能

时间:2013-05-20 17:27:31

标签: c# async-await

我们正在尝试使用异步工作流来处理用户交互。我们的想法是,我们提供了许多基本的可能交互(上传文件,提示某些数据等) - 实现为Web表单 - 我们系统的用户可以编写在服务器上运行的工作流,并结合这些交互:

  var uploadResult = await DoUpload();
  // . . .do stuff with uploadResult .. ..
  var formResult = await DoForm()
  // . . . do stuff with formResult

除了处理“后退”按钮外,我们已经完成了这一切:在上面的示例中,对DoForm()的调用提示输入某些数据,并且因为它是工作流中的第二种形式,它应该具有还有一个“后退”按钮,按下后返回初始上传表单。

显而易见的方法是在每次交互的结果中返回一个BackClicked标志,然后应该由工作流代码进行测试和处理 - 我们更喜欢自动运行的东西。

这是一个简单的控制台应用程序的代码,它复制了我们正在做的事情:

class Program {

  class Step {
    public string Prompt;
    public TaskCompletionSource<string> Tsc;
  }

  /// <summary>User interactions executed so far</summary>
  static List<Step> s_Steps = new List<Step>();
  static bool s_Continue = false;

  /// <summary>Example of a (very basic) user interaction</summary>
  static Task<string> ReadString(string prompt)
  {
    TaskCompletionSource<string> tsc = new TaskCompletionSource<string>();
    try {
      s_Steps.Add(
        new Step() { Prompt = prompt, Tsc = tsc }
      );
      s_Continue = true;
    } catch (Exception exception) {
      tsc.SetException(exception);
    }
    return tsc.Task;
  } // ReadString

  static async Task TheWorkflow()
  {
    var str1 = await ReadString("String 1");
    Console.WriteLine("String 1='{0}'", str1);
    var str2 = await ReadString("String 2");
    Console.WriteLine("String 2='{0}'", str2);
  } // TheWorkflow

  static void Main(string[] args)
  {
    // Start the workflow...
    TheWorkflow();
    // ..and then execute it
    while (s_Continue && s_Steps.Count > 0) {
      s_Continue = false;
    Back:
      var step = s_Steps[s_Steps.Count - 1];
      if (s_Steps.Count > 1) {
        Console.Write(step.Prompt + " [back]: ");
      } else {
        Console.Write(step.Prompt + ": ");
      }
      string result = Console.ReadLine();
      if (s_Steps.Count > 1 && result == "back") {
        s_Steps.RemoveAt(s_Steps.Count - 1);
        goto Back;
      }
      step.Tsc.SetResult(result);
    }
  }
}

在第二个提示符下键入back时,代码会尝试重新执行第一个任务,但由于它已经完成而失败。

有没有办法让它发挥作用 - 即以某种方式调用以前执行的任务的继续?

0 个答案:

没有答案