如何防止操作运行直到完成

时间:2016-01-09 10:30:53

标签: c# operation

我们有通过串口使用mudbus协议的食品登记系统。用户通过设备上的RFID卡注册食物 该系统使用轮询和轮询每个设备并从中请求记录,如果设备有记录发送它和控制后的软件进行一些验证,则返回响应,此操作可能需要很长时间(1到2秒)但我们没有&#39 ; t等待响应并将此操作放在另一个线程上,每次响应准备就绪,我们将其发送到设备,但在响应准备期间我们继续轮询其他设备但我编写的代码表明设备未完成操作未轮询。 当前系统正常工作但一周后出现问题。对于一些用户2个食品注册。这意味着从设备读取相同的记录几次。 (只有一个操作及时运行。从队列中获取的操作)

   public abstract class Operation
   {
        public OperationResult Run(IDevice currentDevice)
        {
            OperationResult result = new OperationResult();
            try
            {

            lock (_activeOpLock)
            {
                if (IsSingleTransaction)
                {
                    var opHashCode = GetHashCode();
                    var oldOp =  ActiveOperations.FirstOrDefault( x => x.DeviceCode == currentDevice.Code && x.OperationCode == opHashCode);

                    //here i return, because operation not completed yet and don't allow same record read from device .
                    //but this code not run correctly.
                    if (oldOp != null)
                        return new OperationResult()
                        {
                            Result = OperationResultType.SingleTransactionError,
                            Message = "This Operatin set to Single Transaction and Another operation use device, and must complete."
                        };

                    //if operation not running i add it to list and remove it when completed.
                    ActiveOperations.Add(new ActiveOperation()
                    {
                        DeviceCode = currentDevice.Code,
                        OperationCode = opHashCode
                    });
                }

            }
            //here the drived class connect to device and send command to it.
           //this class has RunAsync method and allow drived class run 
          //response preparation on another thread and this class 
         //can  check status of it with _isRunningAsync variable.

            result = RunAction(currentDevice);
        }
        catch (Exception ex)
        {
           .....
        }
        finally
        {

            if (IsSingleTransaction)
            {
                if (!_isRunningAsync)
                {
                    RemoveActiveOperation(GetHashCode(), currentDevice.Code);
                }
            }
        }
        return result;
    }

    private void RemoveActiveOperation(int opCode, int deviceCode)
    {
        lock (_activeOpLock)
        {
            var op = ActiveOperations.FirstOrDefault(x => x.OperationCode == opCode && x.DeviceCode == deviceCode);
            if (op != null)
                ActiveOperations.Remove(op);
        }
    }

    protected virtual async void RunAsync(Func<OperationResponse> task, Device currentDevice)
    {
            ...........
            if (IsSingleTransaction && currentDevice != null)
            {
                RemoveActiveOperation(GetHashCode(), currentDevice.Code);
            }
    }

}

我在吹码中使用这个类;

public void RunOperation(Operation op)
{
    foreach(var device in ActiveDevices)
    {           
        //my problem is here, how skip device that not completed operation.
        //i think my design is not correct , but currently i can't change my design.
        op.Run(device);
    }
}

0 个答案:

没有答案