以串行方式在Silverlight中运行异步操作
我理解Silverlight的异步特性,但有一件事经常妨碍我编写有效UI的能力,那就是使用带外加载数据的对象所导致的竞争条件和重入问题。有没有办法强制带外操作按照代码中的顺序进行排序 例如,假设我有一个具有加载方法的对象,其唯一任务是将数据从流加载到文本框中。如果我将其称为Async:以串行方式在Silverlight中运行异步操作,silverlight,asynchronous,Silverlight,Asynchronous,我理解Silverlight的异步特性,但有一件事经常妨碍我编写有效UI的能力,那就是使用带外加载数据的对象所导致的竞争条件和重入问题。有没有办法强制带外操作按照代码中的顺序进行排序 例如,假设我有一个具有加载方法的对象,其唯一任务是将数据从流加载到文本框中。如果我将其称为Async: Object.Load( targetbox1 ); Object.Load( targetbox2 ); Object.Load( targetbox3 ); TargetBox将按任意给定顺序加载。如果出于
Object.Load( targetbox1 );
Object.Load( targetbox2 );
Object.Load( targetbox3 );
TargetBox将按任意给定顺序加载。如果出于任何原因重新输入加载代码,那么两个加载尝试同时进行,并推入相同的文本框,导致异常。这些对象中的大多数都支持事件,因此我可以连接回调:
Object.Loaded ( s, e ) => {
Object.Load( targetbox2 );
Object.Loaded( s, e ) => {
...
}
}
Object.Load( targetbox1 );
但是你看到了嵌套的问题
有没有一种简单的方法可以让这些ops以串行方式运行,这样一个呼叫在前一个呼叫完成之前不会继续进行,而是以一种简单直观的方式进行,可以全面应用?我写了几篇博客文章,并解决了这个问题。第一部分详细描述了解决方案的内部结构,第二部分介绍了如何使用scenerio 以下是一个基于对象加载/加载的伪示例:-
AsyncOperation Load(YourObject subject, TextBox target)
{
return (completed) =>
{
EventHandler eh = null;
eh = (s, args) =>
{
subject.Loaded -= eh;
completed();
}
subject.Loaded += eh;
subject.Load(target);
}
}
这样,您的序列将如下所示:-
IEnumerable<AsyncOperation> LoadTextBoxes()
{
yield return Load(subject1, textbox1);
yield return Load(subject2, textbox2);
yield return Load(subject3, textbox3);
}
主要目标是确保序列有保障,可以任意长,无需令人讨厌的嵌套,可以使用循环,甚至可以在序列中的特定点包含其他代码来执行。这是我们要解决的问题之一。您可能会发现它在这种情况下很有用。您看到了这些,但文档中没有任何内容能够帮助我解决这个问题。反应式框架确实包含了一些有用的部分,但它有点太“象牙塔”,而“钢和混凝土”不够。我们只想做一些简单的事情,而不需要我们掌握一大堆其他的计算机科学知识来完成一些事情。非常有趣的方法。我会尝试一下,让你知道我遇到了什么。
LoadTextBoxes().Run(e =>
{
if (e != null)
{
//Something bad happened.
}
});