ユーザーの操作を処理するために非同期ワークフローを使用しようとしています。基本的な対話 (ファイルのアップロード、データのプロンプトなど) を多数提供し、Web フォームとして実装し、システムのユーザーがこれらの対話を組み合わせてサーバー上で実行されるワークフローを作成できるようにするという考え方です。
var uploadResult = await DoUpload();
// . . .do stuff with uploadResult .. ..
var formResult = await DoForm()
// . . . do stuff with formResult
「戻る」ボタンの処理を除いて、これはすべて機能しています。上記の例ではDoForm()
、いくつかのデータのプロンプトを表示します。これはワークフローの 2 番目のフォームであるため、「戻る」ボタンも必要です。押すと、最初のアップロード フォームに戻ります。
明らかな方法は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);
}
}
}
2 番目のプロンプトで入力back
すると、コードは最初のタスクを再実行しようとしますが、既に完了しているため失敗します。
それを機能させる方法はありますか - つまり、以前に実行されたタスクの継続を何らかの方法で呼び出しますか?