首页 > 解决方案 > 从嵌入式系统更新屏幕

问题描述

我在有一些嵌入式系统的公司工作,我使用后台工作者从系统中读取数据,定时器间隔为 0.5 秒,我知道在那段时间内更新屏幕非常快,但我确信修复我的表单的灵魂正在冻结。到目前为止,我已经尝试从另一个线程(异步函数)执行此操作,我已将线程拆分为 4-5 个后台线程,但没有任何更改,即使我将计时器间隔更改为 1 秒,表单仍然冻结. 我将我从系统接收的数据存储在 HashTables 中,并尝试将所有数据插入 datagridview 中,比如 80 个参数,这意味着 80 个单元格更新到屏幕我知道 0.5 秒很快但有人对我有想法吗?

更新屏幕功能的例子我有几个这样的我认为一个例子就足够了


        public async void updateADCThread(object hash)
        {
            await Task.Run(() =>
            {

                Hashtable table = (Hashtable)hash;


                int j = 12;
                foreach (DictionaryEntry kvp in table)
                {

                    uint key = uint.Parse(kvp.Key + "");
                    int value = (int)uint.Parse(kvp.Value + "");
                    // Console.WriteLine("KEY:" + key.ToString() + "/n Value:" + value.ToString() +"\nRow: " +j.ToString());
                    ChangeUI(() => scCaliTable[2, j--].Value = value.ToString());

                }

            });
           

        }


改变界面

        void ChangeUI(Action action)
        {
            try
            {
                if (InvokeRequired)
                {
                    Invoke(action);
                }
                else
                {
                    action();
                }

            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
            }
        }

代表


  private void scMeasurmentsTabUpdate(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                scMeasurmentsTabDelegate d = new scMeasurmentsTabDelegate(scMeasurmentsTabUpdate);
                this.Invoke(d, new object[] { sender, e });

            }
            else
            {
                try
                {
                    updateSCmeasurmentsStatus(sender, e);
                }
                catch(Exception ex)
                {

                }
               

            }
        }


 public void updateSCmeasurmentsStatus(object sender, EventArgs e)
        {
            form.destBox.Text = comboBoxLRU.Text;
            form.cmdComboBox.Text = "GetStatus";
            ChangeUI(() => statusFooter.Text = "GetStatus");

            //int i;
            int acc = 1;



            ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.SystemFaultsDI_e) + "";

            ///ADC
            for (int i = (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1AVADC_e - (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e; i < Enum.GetNames(typeof(SC_ENUMs.StatusParamID)).Length - 12; i++) // i = 31
            {
                ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i) + "";
            }

            ((TextBox)paramsArray[0]).Text = (acc - 1).ToString();
            NT_MSG.statusTable.Clear();
            form.button1_Click(sender, e);


            if (Program._DEBUG)
            {
                Hashtable peakPosDebug = new Hashtable();
                int index = 2;
                for (int i = 3; i < 31; i++)
                {
                    NT_MSG.statusTable.Add((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i, (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i);
                    if ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i >= (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1P_e)
                    {
                        peakPosDebug.Add((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i, index++);
                    }
                }

                int avgIndex = 14;

                foreach (DictionaryEntry kvp in NT_MSG.statusTable)
                {
                    uint key = uint.Parse(kvp.Key + "");
                    int value = (int)uint.Parse(kvp.Value + "");
                    // Console.WriteLine("KEY:" + key.ToString() + "Value:" + value.ToString());

                    if ((int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1AV_e <= key && key < (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1AV_e + 15)
                    {
                        ChangeUI(() => scCaliTable[0, avgIndex--].Value = value.ToString());
                    }
                    if ((int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1P_e <= key && key < (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1P_e + 13)
                    {
                        ChangeUI(() => scCaliTable[1, Convert.ToInt32(peakPosDebug[(int)key])].Value = value.ToString());
                    }

                }

                return;

            }
            if (form.returnStatus)
            {

                uint general = DLL_UI.res3.values[0];
                BitArray bitArr = new BitArray(new int[] { (int)general }); 
                object arr = bitArr;
           
                updateThread(arr);

                Hashtable table = new Hashtable();

                NT_MSG.statusTable.Remove(((int)SC_ENUMs.StatusParamID.SystemFaultsDI_e));


                table = (Hashtable)NT_MSG.statusTable.Clone();
                if (scUpdateCounter == 0)
                {
                    updateADCThread(table);
                }
               
            }

            NT_MSG.statusTable.Clear();
           

            int avgPosIndex = 0;
            int pPosIndex = 0;


            Hashtable peakPos = new Hashtable();
            Hashtable avgPos = new Hashtable();

           
            acc = 1;
            for (int i = (int)SC_ENUMs.StatusParamID.VinMain_mV_e - (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e; i < (int)SC_ENUMs.StatusParamID.Vin_Main_ADC_e - (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e; i++) // i = 31
            {
                ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i) + "";
                if ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i >= (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1P_e && (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i <= (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU4_P_e)
                {
                    
                        peakPos.Add((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i, pPosIndex++);

                    
                }
                if ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i >= (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1AV_e && (int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i < (int)SC_ENUMs.StatusParamID.PhotoDetectorLRU1_1P_e)
                {
                    
                        avgPos.Add((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i, avgPosIndex++);
   
                }

            }


            mainPeakPos = peakPos;
            mainAvgPos = avgPos;
            ((TextBox)paramsArray[0]).Text = (acc - 1).ToString();
            form.button1_Click(sender, e);

            if (form.returnStatus)
            {    
                Hashtable table = (Hashtable)NT_MSG.statusTable.Clone();
                if (scUpdateCounter == 1)
                {
                    updatePeakAndAVG(table);

                }
            }


            NT_MSG.statusTable.Clear();

            acc = 1;
            ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e).ToString();// 7002 + "";
            for (int i = 46; i < Enum.GetNames(typeof(SC_ENUMs.StatusParamID)).Length; i++)
            {
                ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e + i) + "";

            }
            ((TextBox)paramsArray[0]).Text = (acc - 1).ToString();

            form.button1_Click(sender, e);
            if (form.returnStatus)
            {
     
                NT_MSG.statusTable.Remove(((int)SC_ENUMs.StatusParamID.SystemStatusBitsGeneral_e));
                Hashtable table = (Hashtable)NT_MSG.statusTable.Clone();
                if (scUpdateCounter == 2)
                {
                      updatePeakAndAVGTable(table);
                }
                   
            }

            acc = 1;
            NT_MSG.statusTable.Clear();

            for (int i = 0; i < 3; i++)
            {
                ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.VinMain_mV_e + i) + "";

                ((TextBox)paramsArray[acc++]).Text = ((int)SC_ENUMs.StatusParamID.Vin_Main_ADC_e + i) + "";
            }
            ((TextBox)paramsArray[0]).Text = (acc - 1).ToString();

            form.button1_Click(sender, e);

            if (form.returnStatus)
            { 
                Hashtable table = (Hashtable)NT_MSG.statusTable.Clone();
                if (scUpdateCounter == 3)
                {
                    updateMeasTable(table);
                }
                    
            }
            NT_MSG.statusTable.Clear();

            form.param1.Text = 2 + "";
            form.param2.Text = ((uint)SC_ENUMs.StatusParamID.DigitalInputs_e).ToString();
            form.param3.Text = ((uint)SC_ENUMs.StatusParamID.DigitalOutputs_e).ToString();


            form.button1_Click(sender, e);
            if (form.returnStatus)
            {
                if(DLL_UI.res3.values[0]!= lastGpiosValue[0])
                {
                    updateDigitalInGPIOsThread(DLL_UI.res3.values[0]);
                    lastGpiosValue[0] = DLL_UI.res3.values[0];
                }
                if (DLL_UI.res3.values[1] != lastGpiosValue[1])
                {
                    updateDigitalOutGPIOsThread(DLL_UI.res3.values[1]);
                    lastGpiosValue[1] = DLL_UI.res3.values[1];
                }

            }

            scUpdateCounter++;
            if (scUpdateCounter >= 5)
            {
                scUpdateCounter = 0;
            }
        }


 private void timer1_Tick(object sender, EventArgs e)
{

bg.RunWorkerAsync();
}


 void bg_DoWork(object sender, DoWorkEventArgs e)
 {
            getPoller(sender, e);
       
  }
 private void getPoller(object sender, EventArgs e)
{

 scMeasurmentsTabUpdate(sender, e);
}


谢谢!!

标签: c#

解决方案


我认为这是因为 updateSCmeasurmentsStatus 正在以同步方式调用 updateADCThread。

updateADCThread(table);

在 updateSCmeasurmentsStatus 中更改它

Task.Run(() => updateADCThread(table));

并更改 updateADCThread

public async void updateADCThread(object hash)
{
    Hashtable table = (Hashtable)hash;
        int j = 12;
        foreach (DictionaryEntry kvp in table)
        {
            uint key = uint.Parse(kvp.Key + "");
            int value = (int)uint.Parse(kvp.Value + "");
            // Console.WriteLine("KEY:" + key.ToString() + "/n Value:" + value.ToString() +"\nRow: " +j.ToString());
            ChangeUI(() => scCaliTable[2, j--].Value = value.ToString());
        }
}

如果要在 updateADCThread 之后运行 updatePeakAndAVG,可以在 updateSCmeasurmentsStatus 中使用 await。


推荐阅读