c#charting - 从其他线程异常访问

时间:2017-01-31 11:31:55

标签: c# multithreading charts

今天我试图通过从UC通过UART传输来接收来自项目的数据。

程序只是在中断中接收数据,处理它并显示。

当程序进入我的ChartData方法时,我得到一个例外:

  

未处理的类型' System.InvalidOperationException'   发生在System.Windows.Forms.dll

中      

附加信息:跨线程操作无效:控制   ' chart1'从创建它的线程以外的线程访问   上。   这对我来说很奇怪 - 我认为我的程序中有一个帖子。

我尝试使用纯项目绘制图表,我在Form_Load事件中创建数据 - 一切正常。

我的源代码在这里 - 任何想法?

public partial class Form1 : Form
{
    private List<float> freqList = new List<float>();
    private List<float> magList = new List<float>();
    private float[] fFrequency = new float[numberOfSamples];
    private float[] fMagnitude = new float[numberOfSamples];

    public static int counterOfRecBytes = 0;
    public static int numberOfSamples = 512;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        GetAvailablePorts();

        tb_Rx.Text = "Wprowadź parametry transmisji";

        // Default transmission parameters for testing
        cb_BaudRate.Text = "9600";
        cb_Ports.Text = "COM5";
    }

    /// <summary>
    /// Checks avaiable serialports - for linking my device to other computers
    /// </summary>
    void GetAvailablePorts()
    {
        string[] ports = SerialPort.GetPortNames();
        cb_Ports.Items.AddRange(ports);
        //cb_Ports.SelectedIndex = 0;
    }

    private void bt_connect_Click(object sender, EventArgs e)
    {
        if (bt_connect.Text == "Connect")
        {
            if (cb_Ports.Text == "" || cb_BaudRate.Text == "" || cb_Ports.Text == "")
                tb_Rx.Text = "Nie wybrano jednego z parametrów";
            else
            {
                bt_connect.Text = "Disconnect";

                SerialP.PortName = cb_Ports.Text;
                SerialP.BaudRate = Convert.ToInt32(cb_BaudRate.Text);
                SerialP.StopBits = StopBits.One;
                SerialP.DataBits = 8;
                SerialP.Parity = Parity.None;
                SerialP.Handshake = Handshake.None;
                SerialP.ReadBufferSize = 8 * numberOfSamples + 4;

                SerialP.Open();

                pb_connect.Value = 100;
                tb_Rx.Clear();

                cb_Ports.Enabled = false;
                cb_BaudRate.Enabled = false;
            }
        }
        else
        {
            SerialP.Close();

            bt_connect.Text = "Connect";

            pb_connect.Value = 0;

            bt_connect.Enabled = true;
            cb_BaudRate.Enabled = true;
            cb_Ports.Enabled = true;

            freqList.Clear();
            magList.Clear();

            pb_connect.Value = 0;
            tb_Rx.AppendText(Environment.NewLine + "----Zamknięto połączenie----");
        }
    }

    private void SerialP_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        byte[] bArray = new byte[8 * numberOfSamples+4]; // frequencies (512 samples) and magnitudes (512 values) - each is a single precision float so 4 bytes
        float[] fArray = new float[2*numberOfSamples];
        //bool dataStart = false;

        int previouse = counterOfRecBytes;

        counterOfRecBytes += sp.BytesToRead;

        sp.Read(bArray, previouse, (counterOfRecBytes - previouse));

            if (counterOfRecBytes == 8*numberOfSamples+4)
            {
                for(uint i = 1; i < 2*numberOfSamples+1; i++)
                {

                   // if (freqList.Count == numberOfSamples) freqList.Clear();
                   // if (magList.Count == numberOfSamples) magList.Clear();

                    fArray[i-1] = ByteToFloat(bArray, i);
                    if (i < numberOfSamples+1)    freqList.Add(fArray[i]);
                    else    magList.Add(fArray[i-1]);
                }

            //ListToArray();
            ChartData();

               // if (counterOfRecBytes >= 8 * numberOfSamples + 4) sp.DiscardInBuffer();
                counterOfRecBytes = 0;
            }

    }

    /// <summary>
    /// Changes my recieved bArray to single precision floats
    /// </summary>
    private float ByteToFloat(byte[] input, UInt32 i)
    {
        byte[] array = new[] { input[4 * i], input[4 * i + 1], input[4 * i + 2], input[4 * i + 3] };
        return BitConverter.ToSingle(array, 0);
    }

    /// <summary>
    /// Setting chart data
    /// </summary>
    private void ChartData()
    {
        for (int i = 0; i < numberOfSamples; i++)
        {
            chart1.Series["Widmo"].Points.AddXY(freqList[i], magList[i]);
        }

    }

}

问题解决了 - 我必须做的就是将代码放在下面代替只调用ChartData方法:

if (InvokeRequired)
            {
                Invoke(new MethodInvoker(ChartData));
            }
            else
            {
                ChartData();
            }

0 个答案:

没有答案