因此,在 C# 4.0 的悲惨日子里,我创建了以下“WorkflowExecutor”类,该类通过侵入 IEnumerable 的“yield return”延续以等待 observables 来允许 GUI 线程中的异步工作流。因此,以下代码将在 button1Click 处启动一个简单的工作流程,更新文本,等待您单击 button2,并在 1 秒后循环。
public sealed partial class Form1 : Form {
readonly Subject<Unit> _button2Subject = new Subject<Unit>();
readonly WorkflowExecutor _workflowExecutor = new WorkflowExecutor();
public Form1() {
InitializeComponent();
}
IEnumerable<IObservable<Unit>> CreateAsyncHandler() {
Text = "Initializing";
var scheduler = new ControlScheduler(this);
while (true) {
yield return scheduler.WaitTimer(1000);
Text = "Waiting for Click";
yield return _button2Subject;
Text = "Click Detected!";
yield return scheduler.WaitTimer(1000);
Text = "Restarting";
}
}
void button1_Click(object sender, EventArgs e) {
_workflowExecutor.Run(CreateAsyncHandler());
}
void button2_Click(object sender, EventArgs e) {
_button2Subject.OnNext(Unit.Default);
}
void button3_Click(object sender, EventArgs e) {
_workflowExecutor.Stop();
}
}
public static class TimerHelper {
public static IObservable<Unit> WaitTimer(this IScheduler scheduler, double ms) {
return Observable.Timer(TimeSpan.FromMilliseconds(ms), scheduler).Select(_ => Unit.Default);
}
}
public sealed class WorkflowExecutor {
IEnumerator<IObservable<Unit>> _observables;
IDisposable _subscription;
public void Run(IEnumerable<IObservable<Unit>> actions) {
_observables = (actions ?? new IObservable<Unit>[0]).GetEnumerator();
Continue();
}
void Continue() {
if (_subscription != null) {
_subscription.Dispose();
}
if (_observables.MoveNext()) {
_subscription = _observables.Current.Subscribe(_ => Continue());
}
}
public void Stop() {
Run(null);
}
}
这个想法的聪明部分,使用“yield”延续来做异步工作,取自 Daniel Earwicker 的 AsyncIOPipe 想法:http ://smellegantcode.wordpress.com/2008/12/05/asynchronous-sockets-with-yield- return-of-lambdas/,然后我在其上添加了响应式框架。
现在我在使用 C# 5.0 中的异步功能重写它时遇到了麻烦,但它似乎应该是简单的事情。当我将 observables 转换为任务时,它们只运行一次,而 while 循环第二次崩溃。任何帮助解决这个问题都会很棒。
所有这些说/问,异步/等待机制给了我什么 WorkflowExecutor 没有?有什么我可以用 async/await 做的,而我不能用 WorkflowExecutor 做(给定类似数量的代码)?