Принуждение Flex обновить экран?

ForEach для IEnumerables

public static class FrameworkExtensions
{
    // a map function
    public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
    {
        foreach (var item in @enum) mapFunction(item);
    }
}

Наивный пример:

var buttons = GetListOfButtons() as IEnumerable<Button>;

// click all buttons
buttons.ForEach(b => b.Click());

Прохладный пример:

// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
    .ForEach(item => {
        item.Number = 1;
        item.Str = "Hello World!";
    });

Примечание:

Это не похоже Select, потому что Select ожидает Ваша функция возвращать что-то что касается преобразования в другой список.

ForEach просто позволяет Вам выполнять что-то для каждого из объектов без любых преобразований/манипулирования данными.

я сделал это так, я могу программировать в более функциональном стиле, и я был удивлен, что Список имеет ForEach, в то время как IEnumerable не делает.

Помещенный это в codeplex проект

8
задан 13 July 2009 в 17:09
поделиться

4 ответа

Как упоминалось в других ответах, флэш-проигрыватель является однопоточным, если вы не разбиваете свою работу на отдельные фрагменты, которые могут выполняться в отдельных «кадрах ", вы увидите скачки и заикания в пользовательском интерфейсе, что, по сути, и есть то, что вы видите.

Если вы действительно должны увидеть это сообщение 12%, то этого недостаточно, чтобы аннулировать список отображения, поскольку отображение list не может обновиться до тех пор, пока работа 56% не будет завершена, вы должны явно прервать цикл естественных событий с помощью вызова validateNow () после того, как ваше сообщение было установлено.

Это однако это не лучший способ делать что-то, если производительность вызывает беспокойство. Вы можете обойтись судебным использованием callLater () , чтобы запланировать каждый фрагмент работы по очереди,

9
ответ дан 5 December 2019 в 10:04
поделиться

Попробуйте вызывать invalidateDisplayList () после каждого изменения индикатора выполнения. Примерно так:

Class StatusBar
{

    public function set progress(value:uint):void
    {
        progressBar.value = value;
        progressBar.invalidateDisplayList();
    }
}

Flex имеет цикл аннулирования, который позволяет избежать перерисовки экрана при каждом изменении свойства. Например, если значение свойства изменяется 3 раза за один кадр, оно будет отображаться только с последним установленным значением. Вы можете принудительно перерисовать компонент, вызвав invidateDisplayList (), что означает, что updateDisplayList будет выполняться немедленно вместо ожидания следующего кадра.

2
ответ дан 5 December 2019 в 10:04
поделиться

ActionScript в проигрывателе Flash, как и Javascript в браузере, является псевдопоточным. То есть они однопоточные, но имеют несколько стеков выполнения. Это означает, что вы не можете «засыпать» в конкретном потоке, но вы можете создать новый стек выполнения, который откладывается на более позднее время. Гибкий способ сделать это - функция callLater. Вы также можете использовать функции setTimeout / setInterval. Или вы можете использовать объект таймера, встроенный во флеш-плеер. Или даже прослушиватель событий "ENTER_FRAME". Все это, по сути, позволит вам делать то, что вам нужно, если я прав в отношении причины ваших проблем.

Похоже, у вас есть один «поток», который выполняет большую часть вашей работы, никогда не останавливаясь, чтобы разрешить выполнение других стеков выполнения (потоков *).

Проблема может заключаться в том, что говорит PeZ, но если это не поможет, вы можете попробовать некоторые отложенные вызовы для рабочих классов. Теперь ваш процесс может выглядеть так:

  1. Прогресс инициализирован.
  2. Проделайте некоторую работу.
  3. Обновить индикатор выполнения до 12. (сделать список отображения недействительным)
  4. setTimeout (doMoreWork, 100);
  5. Обновить индикатор выполнения до 52.

(если ваш работник является компонентом UI, вы можете использовать uicomp.callLater (...), в противном случае вам нужно использовать setTimeout / timers / enter_frame для чистых классов AS3).

2
ответ дан 5 December 2019 в 10:04
поделиться

Glenn,

Это совсем не то, как работает потоковая обработка во Flex. Как и многие другие пользовательские интерфейсы, он имеет насос сообщений в главном потоке пользовательского интерфейса (они делают это во фреймах). Когда вы вызываете callLater(), она помещает переданный указатель функции в конец очереди насоса сообщений (на следующий кадр) и немедленно возвращается. Затем функция вызывается, когда насос сообщений закончит обработку всех предшествующих сообщений (например, щелчков мыши).

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

Flex действительно имеет несколько потоков, но они существуют по собственным причинам Adobe и поэтому не доступны пользователю. Я не знаю, есть ли способ гарантировать, что обновление пользовательского интерфейса произойдет в определенный момент, но можно вызвать callLater несколько раз, пока операция не произойдет. Начните с небольшого числа и увеличивайте его до тех пор, пока количество итераций не приведет к желаемому результату. Пример:

// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;

private var _timesCalled:int = 0;

//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
    progressBar.value = progress;
    DoNextFunction();
}

//----------------------------------------------------------------
private function DoNextFunction():void
{
    if( _timesCalled >= TOTAL_CALL_COUNT )
    {
        _timesCalled = 0;
        Function();
    }
    else
    {
        _timesCalled++;
        callLater( DoNextFunction );
    }
}
3
ответ дан 5 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: