1
Answer

C# Multi threading

nil k

nil k

7y
512
1

Hello Friends,

I have created win form application which will read data from TCP and com port from Hardware using modbus and display information on different viewer screen.

For that I have done following code and its seems I am missing something to manage thread properly.

When my viewer screen will be get open that time I have initialing all ports and opening required ports if not open with as below code.

  1. public void InitializeReadingAllInouts()  
  2.    {  
  3.      string query = "select * from portinformation";  
  4.      SQLLiteHelper sql = new SQLLiteHelper();  
  5.      DataTable dt = sql.GetDataTable(query);  
  6.      if (dt.Rows.Count > 0)  
  7.      {  
  8.        for (int i = 0; i < dt.Rows.Count; i++)  
  9.        {           
  10.            inputsList.Add(new InputsDetails { InputsID = currentValuename, LastReadingValue = 0 }); // Here input list is my Statis list and I am using this later  
  11.            ManageHarwareRW.GetInputsDetails(currentValuename, ManageHarwareRW.input_or_output.input);   // This method will open port and will get details from other tables and required information of my port's details and also   
  12.         // also I have taken static list to get al input list information to save more information of each inputs list and also when information contain the tcp or com port information class  
  13.        }  
  14.      }  
  15.    }  
  16.   
  17. // After that I have started to read inputs information in different threads  
  18. public void StartInputsReading()  
  19.    {  
  20.      foreach (InputsDetails item in inputsList)  
  21.      {  
  22.        Thread reading = new System.Threading.Thread(() =>  
  23.          {  
  24.            ReadInputsFromHardware(item.InputsID);  
  25.          });  
  26.        reading.IsBackground = true;  
  27.        reading.Start();  
  28.      }  
  29.    }  
  30.   
  31.      
  32.    private void ReadInputsFromHardware(int inputId)  
  33.    {  
  34.      float lastReadingValue = 0;  
  35.      InputTypeInformation inputTypeInformation = ManageHarwareRW.GetInputInformation(inputId);  
  36.      if (inputTypeInformation == null)  
  37.      {  
  38.        return;  
  39.      }  
  40.      ushort quantity = 2;  
  41.      Int16[] holdingRegisters = new Int16[2];  
  42.      ushort tcpQuantity = (ushort)inputTypeInformation.Quantity;  
  43.      int decimaplPoints = inputTypeInformation.DecimalPlacesRound;  
  44.      while (true)  
  45.      {  
  46.        if (GetInputDetails(inputId) == null)  
  47.        {  
  48.          return;  
  49.        }  
  50.        string currentStatus = "";  
  51.        if (inputTypeInformation.ConnectionType == EnumConfiguration.HardwareconnectionType.COM)  
  52.        {          
  53.          lastReadingValue = ReadHarwareHoldingRegister(inputTypeInformation.SerialPortConfiguration, false, 1, inputTypeInformation.Address, quantity, lastReadingValue, """"ref currentStatus);          
  54.        }  
  55.        else if (inputTypeInformation.ConnectionType == EnumConfiguration.HardwareconnectionType.TCP)  
  56.        {            
  57.          lastReadingValue = ReadFromTCP(inputTypeInformation.TCPPortConfiguration, inputTypeInformation.UnitID, inputTypeInformation.Address, tcpQuantity, holdingRegisters, lastReadingValue, ref currentStatus);          
  58.        }          
  59.        lastReadingValue = (float)Math.Round((double)lastReadingValue, decimaplPoints);  
  60.        SetInputsValues(inputId, lastReadingValue, inputTypeInformation.InputName, inputTypeInformation.Measuretype, currentStatus);  // This will do my inputs list updated and so in all viewer i can get from here.    
  61.        Thread.Sleep(inputTypeInformation.RefreshIntervalTime);  
  62.      }  
  63.    }  
  64.   
  65.   private float ReadHarwareHoldingRegister(SerialPortConfiguration serialPortConfiguration, bool isWrite, byte slaveId, ushort startAddress, ushort numRegisters, float lastValue, string target, string writevalue, ref string currentStatus)  
  66.    {  
  67.      float resultData = lastValue;  
  68.      //lock (locker)  
  69.      //{  
  70.      mutex.WaitOne();  
  71.      try  
  72.      {  
  73.        if (isWrite)  
  74.        {  
  75.          try  
  76.          {  
  77.            if (target.ToLower() == "coil".ToLower())  
  78.            {  
  79.              bool isTrue = false;  
  80.              if (writevalue.ToLower() == "True".ToLower())  
  81.                isTrue = true;  
  82.              int val = 0;  
  83.              if (int.TryParse(writevalue, out val))  
  84.                isTrue = val == 1 ? true : false;  
  85.              serialPortConfiguration.Master.WriteSingleCoil(slaveId, startAddress, isTrue);  
  86.            }  
  87.            else if (target.ToLower() == "register".ToLower())  
  88.            {  
  89.              serialPortConfiguration.Master.WriteSingleRegister(1, startAddress, ushort.Parse(writevalue));  
  90.            }  
  91.          }  
  92.          catch (Exception ex)  
  93.          {              
  94.          }  
  95.          finally  
  96.          {  
  97.             
  98.          }  
  99.        }  
  100.        else  
  101.        {  
  102.          ushort[] registers = serialPortConfiguration.Master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);  
  103.   
  104.          ushort[] data = new ushort[2] { registers[1], registers[0] };  
  105.          float[] floatdata = new float[data.Length / 2];  
  106.          Buffer.BlockCopy(data, 0, floatdata, 0, data.Length * 2);  
  107.          for (int index = 0; index < floatdata.Length; index++)  
  108.          {  
  109.            resultData = (floatdata[index / 2]);  
  110.          }  
  111.        }  
  112.      }  
  113.      catch (Exception ex)  
  114.      {  
  115.         
  116.      }  
  117.      finally  
  118.      {  
  119.        mutex.ReleaseMutex();  
  120.      }  
  121.        
  122.      return resultData;  
  123.    }  
  124.   
  125. /// Now If only reading then it working perfectly but I have output section and each viewer control will do post process based on current value on inputList value. So for output I will have differnet values for slave id, address, etc so I have taken another Static list to store information and if I have already opened port in Input reading then I have taken property and assigning to the output class property.  
  126.   
  127. Each viewer has thread which are getting call as below  
  128.   void work()  
  129.    {       
  130.      while (true)  
  131.      {  
  132.        List<InputsDetails> currentInputs = ManageInputsReading.InputsList(); // Static list we have taken for Reading hardware so we don't have to request each time harware. We can get from List  
  133.        for (int i = 0; i < dt.Rows.Count; i++)  
  134.        {  
  135.          int currentValuename = int.Parse(dt.Rows[i]["id_valuename"].ToString());  
  136.          InputsDetails inputs = currentInputs.Where(q => q.InputsID == currentValuename).FirstOrDefault();  
  137.          if (inputs != null)  
  138.          {             
  139.            if (!this.IsDisposed)  
  140.              Invoke((MethodInvoker)delegate  
  141.              {  
  142.                textboxes.Text = inputs.LastReadingValue  
  143.              }  
  144.              );  
  145.          }  
  146.        }  
  147.        if (currentInputs.Count > 0)  
  148.        {  
  149.          m_latchandoutput.postprocess(inputs.LastReadingValue));  
  150.        }  
  151.        Thread.Sleep(refresh.refreshinterval);  
  152.      }  
  153.    }  
  154.   
  155.  public void postprocess(double valuescalculated)  
  156.    {        
  157.        
  158.          try  
  159.          {  
  160.           int outputId = 123; // this will be Id I have in output command    
  161.            InputTypeInformation inputTypeInformation = ManageHarwareRW.GetOutputInformation(outputId);  
  162.            if (inputTypeInformation == null)  
  163.            {  
  164.              ManageHarwareRW.GetInputsDetails(objConditionValue.commandID, ManageHarwareRW.input_or_output.output);  
  165.              inputTypeInformation = ManageHarwareRW.GetOutputInformation(objConditionValue.commandID);  
  166.            }  
  167.            if (inputTypeInformation == null)  
  168.            {  
  169.              continue;  
  170.            }  
  171.   
  172.            ManageInputsReading manageInputsReading = new ManageInputsReading();  
  173.            if (inputTypeInformation.ConnectionType == EnumConfiguration.HardwareconnectionType.COM)  
  174.            {  
  175.         // Here I am passing object of com seari port which I have taken  
  176.              manageInputsReading.WriteToComHardware(inputTypeInformation.SerialPortConfiguration, inputTypeInformation.Target, inputTypeInformation.UnitID, inputTypeInformation.Address, objConditionValue.resultValue);  
  177.            }  
  178.           
  179.            else if (inputTypeInformation.ConnectionType == EnumConfiguration.HardwareconnectionType.TCP)  
  180.            {  
  181.              manageInputsReading.WriteToTCPHardware(inputTypeInformation.TCPPortConfiguration, inputTypeInformation.Target, inputTypeInformation.UnitID, inputTypeInformation.Address, objConditionValue.resultValue);  
  182.            }  
  183.          }  
  184.          catch (Exception exp)  
  185.          {  
  186.              
  187.          }          
  188.    }  
  189.   
  190.  public void WriteToComHardware(SerialPortConfiguration serialPortConfiguration, string target, byte slaveId, ushort startAddress, string writevalue)  
  191.    {  
  192.      string currentStatus = "";  
  193.      ReadHarwareHoldingRegister(serialPortConfiguration, true, slaveId, startAddress, 0, 0, target, writevalue, ref currentStatus);       
  194.    }  

As in code I have added my comments. When I am trying to call WriteToComHarware Reading to hardware method getting stop working due to port has been closed and no longer enables the reading.


I think something wrong with Threading and Static List I have taken for this.
Please anyone can look into code and suggest me what's the wrong or please suggest me the alternate solution to manage this reading and writing from different thread.
Thanks in advance for your help


 

 
Answers (1)