Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Асинхронная загрузка данных в Chart / 25 сообщений из 42, страница 1 из 2
05.05.2018, 22:21
    #39640803
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Добрый день.

Такая ситация: есть окно - на нём создаётся пользовательский контрол (Grid, Chart, Button-ы).
В конструкторе этого контрола вызывается функция, которая подгружает данные в Chart.
Происходит это синхронно и не очень быстро => окно приложения зависает.
Из другого потока не получается: доступ к UI-элементу не из STA-потока-ошибка.

Я попробовал так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
      {
	  
	  // Окно приложения - MainWindow

	  ADC adelc = AddChart; // AddChart - функция, в которой создаётся контрол
            AsyncCallback cb = new AsyncCallback(MyAsyncCallback);
            IAsyncResult ar = adelc.BeginInvoke("SBER", cb, adelc);


        }

        public void MyAsyncCallback(IAsyncResult ar)
        {
            string s;
            int iExecThread;

            // Because you passed your original delegate in the asyncState parameter
            // of the Begin call, you can get it back here to complete the call.
            ADC dlgt = (ADC)ar.AsyncState;

            // Complete the call.
            dlgt.EndInvoke(ar);
        }

        delegate void ADC(object o);
		
		


И опять же - Вызывающим потоком должен быть STA.
Если просто Dispatcher.BeginInvoke - то выполняется не асинхронно.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
{

// Окно MainWindow

ADC adelc = AddChart;
          
            IAsyncResult ar = adelc.BeginInvoke("SBER", MyAsyncCallback, "");




        }

        public void MyAsyncCallback(IAsyncResult ar)
        {
            MessageBox.Show("kk");
        }

        delegate void ADC(object o);


И - вызывающим потоком должен быть STA.
...
Рейтинг: 0 / 0
05.05.2018, 22:29
    #39640804
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwПроисходит это синхронно и не очень быстро => окно приложения зависает.
Из другого потока не получается: доступ к UI-элементу не из STA-потока-ошибка.Стандартный подход - получить данные асинхронно в DTO (долгая операция), затем быстро перегрузить в UI-контролы в потоке UI.
...
Рейтинг: 0 / 0
05.05.2018, 22:30
    #39640806
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Либо воспользоваться паттерном MVVM - загрузить данные в модель представления, а представление само заберет изменения в нужном потоке
...
Рейтинг: 0 / 0
05.05.2018, 22:55
    #39640815
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Третий вариант - разберитесь почему данные к графику не готовы. Они не должны вычислятся. Это статистика уже прошедших событий.
...
Рейтинг: 0 / 0
05.05.2018, 23:02
    #39640818
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Данные не вычисляются.
Они добавляются на соответствующие области графика.
...
Рейтинг: 0 / 0
05.05.2018, 23:03
    #39640820
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Что такое DTO?
...
Рейтинг: 0 / 0
05.05.2018, 23:14
    #39640822
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwДанные не вычисляются.
Они добавляются на соответствующие области графика.вопрос был почему долго.
Какая разница добавляются или вытягиваются?
...
Рейтинг: 0 / 0
05.05.2018, 23:28
    #39640824
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
...
Рейтинг: 0 / 0
05.05.2018, 23:28
    #39640825
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
...
Рейтинг: 0 / 0
05.05.2018, 23:29
    #39640826
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwфункция, которая подгружает данные в Chart.надо разделить наmraklbrwфункция, которая подгружаетиmraklbrwданные в Chart.
...
Рейтинг: 0 / 0
06.05.2018, 12:26
    #39640895
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Попробовал так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
async void VeryLongMethod()
        {
            string access = await AddChart("SBER2");
        }

async Task<string> AddChart(object o)
        {
            // Загрузка контрола
        }


И вызываю функцию VeryLongMethod().

Выполняется не асинхронно.
...
Рейтинг: 0 / 0
06.05.2018, 12:36
    #39640898
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwИ вызываю функцию VeryLongMethod().

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

А что касается задачи - еще раз.
ДЛИТЕЛЬНУЮ операцию получения данных (что у вас там, загрузка из БД, загрузка из интернета и т.п.) нужно выполнить асинхронно (и не через async void) и сложить эти данные в DTO. А также произвести все манипуляции над ними.

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

Тогда тормозов не будет
...
Рейтинг: 0 / 0
06.05.2018, 12:41
    #39640900
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwПопробовал так:
это монолог а не диалог.
- почему у меня 1000 строк показываются быстро в таблице. А у вас медленно?
На вопросы не отвечаете?
...
Рейтинг: 0 / 0
06.05.2018, 12:42
    #39640902
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwВ конструкторе этого контрола вызывается функция, которая подгружает данные в Chart.констуктор (а вообще это неверный подход) пусть принимает на вход данные, а не загружает их сам. А по хорошему, все данные контрол должен получить через свойства, а конструктор - быть без параметров
...
Рейтинг: 0 / 0
06.05.2018, 12:58
    #39640909
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
В конструкторе контрола почти ничего не делается.
Создание контрола занимает примерно до 3 сек (тоже много, да).
После этого вызывается функция констрола SetQuotes, в которой уже в Chart добавляются свечи из уже готового HashSet<Candle>, т.е. данные готовы - в течении 15 секунд они (6000 свеч примерно) загружаются в Chart.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
            candleSeries = new Series("SeriesCandle")
            {
                ChartType = SeriesChartType.Candlestick, // Тип - японские свечи
                YAxisType = AxisType.Secondary,
                ChartArea = "ChartAreaCandle",
                ShadowOffset = 2,
                YValuesPerPoint = 4
            };

            _chartForCandle.Series.Add(candleSeries);

            for (int i = 0; i < quotes.Count; i++)
            {
                // Добавление свечи
                candleSeries.Points.AddXY(i, quotes.ElementAt(i).Low, quotes.ElementAt(i).High, quotes.ElementAt(i).Open, quotes.ElementAt(i).Close);
                // Добавление подписи-времени
                candleSeries.Points[candleSeries.Points.Count - 1].AxisLabel = quotes.ElementAt(i).Date.ToString(CultureInfo.InvariantCulture);
                // Назначение цветов свечей
                if (quotes.ElementAt(i).IsPositive) candleSeries.Points[candleSeries.Points.Count - 1].Color = System.Drawing.Color.FromName(Program_Settings.PositiveCandleColor);
                else candleSeries.Points[candleSeries.Points.Count - 1].Color = System.Drawing.Color.FromName(Program_Settings.NegativeCandleColor);
            }



Т.е. вот этот цикл и занимает кучу времени.
...
Рейтинг: 0 / 0
06.05.2018, 13:02
    #39640911
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Ужас!
mraklbrw
Код: c#
1.
quotes.ElementAt(i)

нафига тут ElementAt?
...
Рейтинг: 0 / 0
06.05.2018, 13:03
    #39640912
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
HashSet<Candle> - quotes[i] - так обратиться нельзя.
...
Рейтинг: 0 / 0
06.05.2018, 13:04
    #39640913
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrw6000 свеч примерно
дайте скрин свой или похожий из гугла.
По 5 свечей на пиксель?
...
Рейтинг: 0 / 0
06.05.2018, 13:05
    #39640914
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Почитайте, что такое Enumerator, как работает Linq и т.п.
У вас проход по массиву quotes при 6000 элементах будет выполнен 6*6000 раз
замените for на foreach
немедленно!
и никогда так больше не делайте!
...
Рейтинг: 0 / 0
06.05.2018, 13:06
    #39640915
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrwHashSet<Candle> - quotes[i] - так обратиться нельзя.потому что вообще не надо к нему обращаться.
...
Рейтинг: 0 / 0
06.05.2018, 13:08
    #39640918
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
...
Рейтинг: 0 / 0
06.05.2018, 13:12
    #39640919
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Далее - вот это тутmraklbrw
Код: c#
1.
candleSeries.Points[candleSeries.Points.Count - 1]

нафига несколько раз? Что мешает сначала подготовить точку, а потом выполнять AddXY?

И вообще, нельзя ли подготовить массив точек заранее (асинхронно), а потом присвоить его candleSeries.Points? (тут я не знаю, позволит ли это сделать чарт, но это было бы логично)
...
Рейтинг: 0 / 0
06.05.2018, 13:14
    #39640921
mraklbrw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Shocker.ProПочитайте, что такое Enumerator, как работает Linq и т.п.
У вас проход по массиву quotes при 6000 элементах будет выполнен 6*6000 раз
замените for на foreach
немедленно!
и никогда так больше не делайте!

Исправил, выполнение данного участка кода ~ 1-1.5 сек.
Понял ошибку, действительно, было очень глупо, буду дальше смотреть.
...
Рейтинг: 0 / 0
06.05.2018, 13:17
    #39640923
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
mraklbrw1-1.5 сек.
Тогда, я так понял, топик решён.
Удачи!
...
Рейтинг: 0 / 0
06.05.2018, 13:22
    #39640925
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная загрузка данных в Chart
Shocker.ProИ вообще, нельзя ли подготовить массив точек заранее (асинхронно), а потом присвоить его candleSeries.Points? (тут я не знаю, позволит ли это сделать чарт, но это было бы логично)Но даже если не позволит присвоить массив точек, все равно логично подготовить сначала массив точек вне конструктора, а в конструкторе его только добавить. Это то, о чем я твержу вам с самого начала - не надо получать данные внутри конструктора, надо их сначала подготовить, а потом грузить в контрол
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Асинхронная загрузка данных в Chart / 25 сообщений из 42, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]