2015-07-15 5 views
0

У меня есть TabConrol, что когда пользователь делает определенные вещи, добавляется новый TabItem. На этой вкладке есть Рамка, которая будет содержать желаемый Page.XAML. Все это прекрасно работает;Загрузка WPF Frame async

private void addNewTab() 
{ 
    TabItem tab = new TabItem(); 
    Grid g = new Grid(); 
    Frame f = newFrame(); 
    g.Children.Add(f); 
    tab.Content = g; 
    MyTabControl.Items.Add(tab); 
    MyTabControl.SelectedItem = tab; 
} 

private Frame newFrame() 
{ 
    Frame f = new Frame(); 
    //Full logic for Frame removed 
    f.Navigate(new MyPage()); 
    return f; 
} 

Вопросы, возникающие при загрузке нового Frame могут занять некоторое время. Поэтому я хотел сделать это асинхронно. Поэтому, когда он загружается, может быть загрузочная анимация. Я понял, что это сработает;

private async void addNewTab() 
{ 
    TabItem tab = new TabItem(); 
    Grid g = new Grid(); 

    var test = Task<Frame>.Factory.StartNew(() => newFrame(selectTab, value)); 
    await test; 
    f = test.Result; 

    g.Children.Add(f); 
    tab.Content = g; 
    MyTabControl.Items.Add(tab); 
    MyTabControl.SelectedItem = tab; 
} 

private Frame newFrame() 
{ 
    Frame f = new Frame(); 
    //Full logic for Frame removed 
    f.Navigate(new MyPage()); 
    return f; 
} 

Проблема заключается в том, что он возвращает ошибку следовать по Frame f = new Frame(); в newFrame() в перспективе;

Исключение типа «System.InvalidOperationException» произошло в PresentationCore.dll, но не был обработан в пользовательском коде

Дополнительная информация: Вызывающий поток должен быть STA, так как многие компоненты пользовательского интерфейса требуют этого.

Начав думать, что я пытаюсь решить это неправильно. Каков наилучший способ справиться с этим?

+0

Возможный дубликат [Как запустить что-то в потоке STA?] (Http://stackoverflow.com/questions/2378016/how-to-run-something-in-the-sta-thread) – Seb

ответ

4

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

Вы не можете создавать фактические компоненты пользовательского интерфейса на фоновом потоке; вот что говорит вам исключение.

Но вы можете построить данные на фоновом потоке, а затем позже нагрузки это в UI:

private async Task addNewTabAsync() 
{ 
    TabItem tab = new TabItem(); 
    Grid g = new Grid(); 

    var data = await Task.Run(() => getData(value)); 
    Frame f = new Frame(); 
    // Fill out frame with data. 
    f.Navigate(new MyPage()); 

    g.Children.Add(f); 
    tab.Content = g; 
    MyTabControl.Items.Add(tab); 
    MyTabControl.SelectedItem = tab; 
} 

Следует заметить, что я изменил async void к async Task (и добавили суффикс Async), и изменен StartNew на Run, чтобы следовать лучшим практикам.

Смежные вопросы