Запускать асинхронные операции в Silverlight поочередно - PullRequest
3 голосов
/ 16 июня 2011

Я понимаю асинхронную природу Silverlight, но одна вещь, которая постоянно мешает моей способности программировать эффективные интерфейсы, - это условия гонки и возникающие проблемы, вызванные использованием объектов, которые загружают данные вне полосы. Есть ли способ принудительно упорядочить внеполосные операции, как они есть в коде?

Например, представьте, что у меня есть объект с методом Load, единственной задачей которого является загрузка данных из потока в текстовое поле. Если я назову это Async как таковой:

Object.Load( targetbox1 );
Object.Load( targetbox2 );
Object.Load( targetbox3 );

Целевые ящики будут загружаться, но в любом заданном порядке. Если я повторно введу код загрузки по какой-либо причине, то две попытки будут происходить одновременно и выдвигаться в одно и то же текстовое поле, приводящее к исключению. Большинство из этих объектов поддерживают события, и я мог бы подключить обратный вызов как таковой:

Object.Loaded ( s, e ) => {

   Object.Load( targetbox2 );

    Object.Loaded( s, e ) => {
     ...
    }
}

Object.Load( targetbox1 );

Но вы видите проблему с вложенностью.

Есть ли какой-нибудь простой способ запустить эти операции последовательно, чтобы один вызов не продолжался до тех пор, пока не завершится предыдущий процесс, а сделать это простым, интуитивно понятным способом, который можно применить по всем направлениям?

1 Ответ

3 голосов
/ 16 июня 2011

Я написал пару статей в блоге здесь и здесь , посвященных этой проблеме.Первый подробно описывает внутреннюю часть решения, второй описывает, как использовать scenerio.

Вот псевдо-пример базы вашего объекта Load / Loaded: -

 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.
   }
});

Основная цель заключается в том, что последовательность гарантируется, может быть столько, сколько выкак без вложений, может использовать циклы и даже включать другой код для выполнения в определенных точках последовательности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...