Заполнение диаграммы WPF в BackgroundWorker - PullRequest
0 голосов
/ 30 марта 2011

Моя программа WPF загружает данные из нескольких CSV-файлов в линейную диаграмму (каждый файл в свой собственный LineSeries).Это занимает некоторое время (делает GUI непригодным для использования), поэтому я хотел выполнить эту операцию в отдельном потоке и отобразить сообщение о загрузке (BusyIndicator из расширенного инструментария WPF).

К сожалению, когда я пытаюсь создать LineSeriesв BackgroundWorker я получаю исключение: «Вызывающий поток должен быть STA, потому что это требуется для многих компонентов пользовательского интерфейса».Я пытаюсь скопировать диаграмму графического интерфейса, заполнить копию, а затем завершить к диаграмме графического интерфейса.Так что это не должно пытаться получить доступ к элементу управления из другого потока.

</p> <pre><code> /// <summary> /// Loads data from the collections into the chart /// </summary> private void populateChart() { // Begin working: Pass chart and data to the worker (wrapped in a class) this.chartWorker.RunWorkerAsync(new ChartWorkerArgs() { chart = chart, data = model.getAllCollections() }); } /// <summary> /// Populates a provided Chart with provided data. /// </summary> private void chartWorker_DoWork(object sender, DoWorkEventArgs e) { // ... // Iterate through each one foreach (XYCollection collection in data) { // Create a new LineSeries and configure it LineSeries ls = new LineSeries(); // <-----------ERROR ls.ItemsSource = collection; ls.IndependentValueBinding = new Binding("X"); ls.DependentValueBinding = new Binding("Y"); ls.Title = collection.Name; chart.Series.Add(ls); } // Send the pouplated chart back e.Result = chart; } /// <summary> /// After chart has been populated (or cancelled), update chart. /// </summary> private void chartWorker_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { // ... // Set the GUI's chart as the newly populated chart this.chart = (Chart)e.Result; // ... }

Из того, что я читал в другом месте, это неможно сделать BackgroundWorker STA, поэтому есть ли другой способ загрузить диаграмму с данными без зависания графического интерфейса?

Спасибо

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

Вы не должны получать доступ к элементам пользовательского интерфейса вашего фонового работника. Пользовательский интерфейс WPF является (почти) однопоточным. Это означает, что вы должны загрузить свои данные в фоновом потоке, а для обновления пользовательского интерфейса вызвать нужную функцию в потоке пользовательского интерфейса (используя Dispatcher.Invoke ).

Таким образом, в основном вы должны выполнить всю необходимую (и длительную) подготовку данных в фоновом потоке (на самом деле не имеет значения, берете ли вы BackgroundWorker или любое другое из многочисленных средств многопоточности), кроме создания пользовательского интерфейса элементы и поддержание визуального состояния должны быть Invoke d в основном потоке.

Здесь вы можете найти простой пример.

0 голосов
/ 30 марта 2011

Вы можете использовать простую тему.Тогда у вас есть контроль (владение), чтобы сделать его STA.

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

...