简体   繁体   中英

In my Blazor server app I get problems if multiple clients are reading data from remote machine over a sourced service. With single client it is OK

Hello I use a third party dll in my Blazor server app. This dll is for connecting to remote PLC's and reading their PLC data. The data reading method (doNCK_ReadMixEx) works only with static variables (Otherwise reading is not working) I use this method in a sourced service, so that every client should be able to read data from different PLC's periodically (every second) at the same time. If only one client is reading data from a remote PLC it works absolutely fine. But if two clients try to read data from different PLC's at the same time the data is being read paritaly, but frequently I see instead of the required data different characters or numbers. I am not sure whether I have a problem in calling the method, or whether the static variables of the method are causing the problem. Here is my code:

Razor page (Here i am triggering the periodical reading)

 @page "/PLC_Status"
 @inject Deltalogic Deltalogic
 @inject Parameter_840D Parameter_840D
 <button @onclick="Read_CNC_Status">Start Reading</button>

Razor.cs

 public async Task Read_CNC_Status()
    {
        Reading_active = true;
                    
            for (int k=0; k<=200;k++)
            {
                Read_PLC_Data();
                InvokeAsync(() =>
                {
                    StateHasChanged();
                });
                await Task.Delay(1000);

                if (k == 200)
                {
                    Stop_CNC_Status();
                }
            }
        }
    }

 public void Read_PLC_Data()
 //Here the doNCK_ReadMixEx is called for each PLC parameter 
    {
       Parameter_840D.Par_840D_Channel_Status(Deltalogic.channel_no); //Pick-up parameters for variable-1          
       Deltalogic.doNCK_ReadMixEx(Deltalogic.MAE_Status_DevNr, 5000, out Deltalogic.MAE_Status_Mode)
       Parameter_840D.Par_840D_Prog_Status(Deltalogic.channel_no); //Pick-up parameters for variable-2          
       Deltalogic.doNCK_ReadMixEx(Deltalogic.MAE_Status_DevNr, 5000, out Deltalogic.MAE_Status_State_CH[1);
       Parameter_840D.Par_840D_Machine_Active_Workpiece(Deltalogic.channel_no);//Pick-up parameters for variable-3          
       Deltalogic.doNCK_ReadMixEx(Deltalogic.MAE_Status_DevNr, 5000, out Deltalogic.MAE_Status_WPD_CH[Deltalogic.channel_no]);
  // and other PLC parameters....
    }

Parameter_840D (Sourced service for the paramterization of doNCK_ReadMixEx)

// The parameters of doNCK_ReadMixEx have to be defined as static. If not, data cannot be read
public class Parameter_840D
{
    [Inject]
    Deltalogic Deltalogic { get; set; }

    public static byte channel_no = 1;
    public static ushort Parameter_No;
    public static ushort column;
    public static AGL4.NCK_Block block_type;
    public static AGL4.NCK_Area area;
    public static ushort row;
    public static byte rowCount;
    public static byte Unit;
    public static int Bufflen;
    public static byte Buff;
    public  static AGL4.NCK_DDEVarFormat DD

    //Methods that just describes the parameter for each PLC variable

}

Deltalogic (Sourced service for PLC reading methods)

public class Deltalogic
{
    [Inject]
    Parameter_840D Parameter_840D { get; set; }

    public Int32 doNCK_ReadMixEx(Int32 connnr, Int32 timeout, out string NCK_Data)
    {
        //Reset_Parameter_value();
        NCK_Data = "";
        Parameter_840D Parameter_840D = new Parameter_840D();
        connnr = Return_Connect_NCK;
        Int32 result = 0;
        AGL4.NckDataRW[] rwfield = new AGL4.NckDataRW[1];
        rwfield[0] = new AGL4.NckDataRW();
        rwfield[0].Area = Parameter_840D.area;
        rwfield[0].Block = Parameter_840D.block_type;
        rwfield[0].Column = Parameter_840D.column;
        rwfield[0].Row = Parameter_840D.row;
        rwfield[0].RowCount = Parameter_840D.rowCount;
        rwfield[0].Unit = Parameter_840D.Unit;
        rwfield[0].DDEVarType = Parameter_840D.DDEVarType;
        rwfield[0].BuffLen = Parameter_840D.Bufflen;
        rwfield[0].Buff = new Byte[rwfield[0].BuffLen];          
        rwfield[0].Result = 0;
        result = AGL4.NCK_ReadMixEx(connnr, ref rwfield, timeout);
  }

You want to create a wrapper service and make it thread safe. You can do this with the lock{...} statement if the code is not asynchronous. If it is async, you can use the SemaphoreSlim which can lock a resource to only allow a configurable amount of threads simultaneously; you want to configure it to 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM