Приложение использует Caliburn.Micro и его экраны для отображения вкладок для пользователя.Как запустить код после инициализации экрана в первый раз?
Мне известен метод IScreen.OnInitialize(), который вызывается перед тем, как экран становится видимым. Я хотел бы, чтобы код запускался, экран полностью виден пользователю - вкладка, представляющая экран, должна быть там, но необязательно должна быть обязательно выбрана.
Я хотел бы запускать загрузку данных сразу после того, как экран полностью инициализирован и виден (и большая часть кода запускается в потоке пользовательского интерфейса изначально без маршалинга).
Как это выглядит сейчас.
public class MyViewModel :
Conductor<IScreen>.Collection.OneActive,
IHandleWithTask<DatabaseItemChangedMessage>
{
// This method is called by EventAggregator
public async Task Handle(DatabaseItemChangedMessage message)
{
await this.LoadData(true);
}
protected override void OnInitialize()
{
base.OnInitialize();
Task.Factory.StartNew(() => this.LoadData(false).Wait()).ContinueWith(
task =>
{
if (task.Exception != null)
{
Execute.OnUIThread(
() =>
{
App.HandleException(task.Exception);
this.TryClose();
});
}
});
}
protected async Task LoadData()
{
try
{
this.WorkStarted("Loading data...");
TLoadedData loadedData;
ISession transaction = null;
// using (var transaction = this.DataItemRepository.BeginTransaction())
// {
loadedData = await this.LoadDataInternal(transaction);
// transaction.Commit();
// }
Execute.OnUIThread(() => this.SetLoadedData(loadedData));
}
finally
{
this.WorkFinished();
}
}
protected virtual void SetLoadedData(TLoadedData loadedData)
{
// Updates CollectionView's source using loadedData
}
protected virtual async Task<TLoadedData> LoadDataInternal(ISession session)
{
// loads data from database and returns them
}
protected virtual void WorkStarted(string description)
{
// Sets properties using to display progress
}
protected virtual void WorkFinished()
{
// Unsets properties using to display progress
}
}
// Just an empty class for EventAggregator purposes
public class DatabaseItemChangedMessage
{
}
// Stores data loaded from the database
public class TLoadedData
{
}
Вы синхронно ожидания на асинхронных методов. Не делай этого. 'ждут их. – Servy
Кроме того, вам не нужно использовать 'Execute.OnUIThread' вообще в такой программе, если вы правильно используете TPL; из-за того, что продолжения будут ориентироваться на исходный контекст. – Servy
1) Если я удаляю 'Execute.OnUIThread' в методе OnInitialize', вызывающий поток должен быть STA, потому что для этого требуется множество компонентов пользовательского интерфейса." бросается при создании экземпляра окна внутри метода «App.HandleException». – alik