Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.12.2015, 22:50   #1
terrrrry
 
Регистрация: 23.12.2015
Сообщений: 2
Печаль Передача chart в поток через BeginInvok

Добрый день.
Идея в следующем. Из главного окна приложения вызывать во второстепенном потоке метод который будет вычислять и строить графики на chart1 и chart2. И оставлять на главной форме активной только одну кнопку чтобы можно было выйти из этого метода раньше(если пользователь ввел некорректные данные, метод может выполняться долго). Создается делегат этого метода. И из второстепенного потока через BeginInvoke он через делегат вызывается. Но при отладки проекта вылетает ошибка, что элемент управление не может использоваться двумя потоками. Ругается именно на chart. Вот листинг программы.
Сначала я определяю делегат
Код:
namespace Терминал
{
    public delegate double[,] DelegateForpaint_Magnitude_Response(ushort freq_min, ushort freq_max, ushort size_step, 
        double cof_del_in, double A0, double A1, ushort scale,Chart chart1, Chart chart2,
        int char2_series, string PortName, Int32 BaudRate, byte namber_channel_DAC, byte namber_channel_ADC, 
              Label lable1, bool Logarithmic_amp);
    public partial class Form1 : Form
    {
... и тд...
Затем в обработчике private void button4_Click_1 вызывается следующая функция
Код:
  void Magnitude_Response_Run(int char2_series_0)
        {
            data_for_thread_for_paint_Magnitude_Response data_for_thread_for_paint_Magnitude_Response =  
                     new data_for_thread_for_paint_Magnitude_Response();
            data_for_thread_for_paint_Magnitude_Response.freq_min = ushort.Parse(comboBox7.Text);
            data_for_thread_for_paint_Magnitude_Response.freq_max = ushort.Parse(comboBox9.Text);
            data_for_thread_for_paint_Magnitude_Response.size_step = ushort.Parse(comboBox10.Text);
            data_for_thread_for_paint_Magnitude_Response.cof_del_in = Convert.ToDouble(comboBox13.Text);
            data_for_thread_for_paint_Magnitude_Response.A0 = Convert.ToDouble(comboBox8.Text);
            data_for_thread_for_paint_Magnitude_Response.A1 = Convert.ToDouble(comboBox12.Text);
            data_for_thread_for_paint_Magnitude_Response.scale = 0;
            data_for_thread_for_paint_Magnitude_Response.Logarithmic_amp = false;
            data_for_thread_for_paint_Magnitude_Response.comboBox2_Text = comboBox2.Text;
            data_for_thread_for_paint_Magnitude_Response.comboBox3_Text = comboBox3.Text;
            data_for_thread_for_paint_Magnitude_Response.comboBox4_Text = comboBox4.Text;
            if (radioButton3.Checked)
                data_for_thread_for_paint_Magnitude_Response.scale = 0;
            if (radioButton8.Checked)
                data_for_thread_for_paint_Magnitude_Response.scale = 1;
            if (radioButton1.Checked)   // Выбираем шкалу по у
                data_for_thread_for_paint_Magnitude_Response.Logarithmic_amp = false;
            if (radioButton2.Checked)
                data_for_thread_for_paint_Magnitude_Response.Logarithmic_amp = true;
 
            data_for_thread_for_paint_Magnitude_Response.char2_series = char2_series_0;
 
 
            //System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            thread_for_paint_Magnitude_Response = new Thread(new ParameterizedThreadStart(Magnitude_Response)); 
            thread_for_paint_Magnitude_Response.Start(data_for_thread_for_paint_Magnitude_Response);
            thread_for_paint_Magnitude_Response.IsBackground = true;
        }
thread_for_paint_Magnitude_Response
        void Magnitude_Response(object data_for_thread_for_paint_Magnitude_Response)
        {
        DelegateForpaint_Magnitude_Response Delegate_paint_Magnitude_Response = 
    new DelegateForpaint_Magnitude_Response(ФУНКЦИИ_УПРАВЛЕНИЯ_ИПО.ФУНКЦИИ_УПРАВЛЕНИЯ_ИПО.paint_Magnitude_Response);
 
            data_for_thread_for_paint_Magnitude_Response data =  
        (data_for_thread_for_paint_Magnitude_Response)data_for_thread_for_paint_Magnitude_Response;
            IAsyncResult ar = Delegate_paint_Magnitude_Response.BeginInvoke(data.freq_min, data.freq_max, 
                    data.size_step, data.cof_del_in, data.A0, data.A1, data.scale, chart1, chart2,
                data.char2_series, data.comboBox4_Text, Int32.Parse("256000"), Byte.Parse(data.comboBox2_Text), 
                          Byte.Parse(data.comboBox3_Text), label4, data.Logarithmic_amp, null, null);
        }
Если расскоментарить строчку
Код:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
соответственно все передается. Но в процессе выполнение появляется ошибка.
Она появляется только тогда, когда в коллекцию точек chart1 методами
Код:
chart1.Series[0].Points.AddXY 
chart1.Series[1].Points.AddXY
Я пытаюсь добавить более 1500 точек где то. Причем они делятся между сериями.

Так вот можно ли как то корректно передать в фоновый поток chart???
Или как увеличить количество памяти выделенное под точки chart1.Series[0].Points и chart1.Series[1].Points???

Последний раз редактировалось Stilet; 30.12.2015 в 10:22.
terrrrry вне форума Ответить с цитированием
Старый 24.12.2015, 15:22   #2
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

посмотрите в сторону оператора lock.
хотя по мне так лучше переработать механизм обработки.
Например все ваши второстепенные потоки занимаются только расчетом данных и складывают их в некий буфер в том же классе что и чарты.
А в основном потоке крутится самый простой таймер и выводит данные в чарт. То есть доступ будет только у таймер... а у потоков будет у каждого свой буфер. и никто никому мешать не будет.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 29.12.2015, 21:39   #3
terrrrry
 
Регистрация: 23.12.2015
Сообщений: 2
По умолчанию

Там очень много переделывать(((

Для корректных изменений в chart. Я каждый раз при обращении к chart из другого потока проверяла используется ли он каким либо потоком. Если да то ставила обращение в очередь
Код:
 if (chart2.InvokeRequired)
            {
                chart2.Invoke((MethodInvoker)delegate { chart2.ChartAreas[0].AxisX.Minimum = freq_min; });
            }
            else
            {
                chart2.ChartAreas[0].AxisX.Minimum = freq_min;
            }

Последний раз редактировалось Stilet; 30.12.2015 в 10:22.
terrrrry вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача параметра в поток Sanprof Общие вопросы Delphi 10 08.07.2015 14:11
.NET 4.x Передача в новый поток метода с параметрами из другого класса maxspace C# (си шарп) 1 25.03.2013 14:26
Потоки: передача параметров в поток [MoNAMur] Общие вопросы Delphi 1 09.11.2011 17:23
Создание потока,передача функции в поток asdasys Помощь студентам 4 25.02.2011 17:30
Передача параметра в поток joker Win Api 10 22.12.2007 12:53