Синхронизация C # с обновлениями экрана - PullRequest
1 голос
/ 09 февраля 2011

У меня есть следующая проблема: Мое приложение обновляет экран и после этого должно сделать снимок экрана с новым представлением.
Код выглядит следующим образом:

    public ViewModelBase Screen {
        get {
            if (_screen == null) {
                Screen = new DataSourceChooserScreenViewModel(this);
                History.ChangeHistory(ADD_ITEM);
            }
            return _screen;
        }
        set {
            _screen = value;
            OnPropertyChanged("Screen");

            System.Windows.Forms.Application.DoEvents();
        }
    }

Обновление экрана выполняется в «OnPropertyChanged (« Экран »)», а снимок экрана создается в «History.ChangeHistory (ADD_ITEM)».
Методы, вызывающие установщик для «Screen», следуют той же схеме:

//Do something
Screen = otherScreen;
History.ChangeHistory(ADD_ITEM);
//Do something else

И вот проблема: Снимок экрана сделан до обновления экрана, хотя порядок выполнения говорит о другом.

Чтобы решить проблему самостоятельно, я попробовал несколько вещей:
Ожидание в ADD_ITEM
Ожидание по таймеру в ADD_ITEM
Использование асинхронных потоков с ожиданием на PropertyChangedEvent через BeginInvoke () и EndInvoke ()
Использование System.Windows.Forms.Application.DoEvents ()

Все попытки имели одинаковый результат: скриншоты были сделаны до того, как экран обновился. При попытке использовать таймеры, которые я выяснил, экран обновляется после выполнения ADD_ITEM. Поэтому я предлагаю компилятору выполнить неявную многопоточность, и я не знаю, как это исправить / предотвратить.

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 09 февраля 2011

Когда мне нужно сделать что-то подобное, я всегда использую событие таймера, которое сработает ПОСЛЕ того, как все обработано. Это будет одноразовое событие таймера, и использование будет примерно таким:

Чтобы выстрелить:

Timer t=new Timer();
t.Tick+=DoAfter;
t.Interval=100;
t.Start();

Что нужно сделать, это здесь:

void DoAfter(object Sender, SomeArgs a)
{
    Timer t=(Timer)Sender;
    t.Stop();
    t.Dispose();
    //  perform your stuff here
    DoStuff();
}

Таким образом, у вас есть хороший шанс, что цикл сообщений сделает все, и обновления экрана завершатся ДО запуска таймера.

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