WCF Multiple concurrency issue with instance method call

守給你的承諾、 提交于 2019-12-24 09:08:30

问题


I have created a WCF service with the configuration as InstanceMode=PerCall and ConcurrencyMode=Multiple.

But I am getting problem in the synchronization with one of the instance method. It sometimes does not get called with right set of Class property values.

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class InvestorService : IInvestorService

 public void ProcessPartnerChunk(short PartnerChunkTypeId, int JobID, int? PartnerID, string serializedChunk, string ClientName)
    {
        PartnerChunkProcessor pcp = new PartnerChunkProcessor(JobID, PartnerID, serializedChunk, ClientName);

        switch ((PartnerChunkType)PartnerChunkTypeId)
        {
            case PartnerChunkType.ChunkTypeX:
                pcp.ProcessChunkStageX();
                break;
            case PartnerChunkType.ChunkTypeY:
                pcp.ProcessChunkStageY();
                break;                
            default: break;
        }

PartnerChunkProcessor looks like this:-

  public class PartnerChunkProcessor
{
    private static object _syncLocker = new object();

    #region "Properties"
    public int? PartnerID { get; set; }
    public int K1JobId { get; set; }
    public string SerializedChunk { get; set; }

    public string Client { get; set; }
    #endregion

    #region "Constructors"
    private PartnerChunkProcessor() { }

    public PartnerChunkProcessor(int K1JobID, int? PID, string Chunk, string ClientName)
    {
        K1JobId = K1JobID;
        PartnerID = PID;
        SerializedChunk = Chunk;
        Client = ClientName;
    }

    #endregion

    public void ProcessChunkStageX()  //IDMS_PartnerTradeGroups
    {           

        DataModelEntities dmxContext = new DataModelEntities();                      

        //[Step-1]
        //Deserialize the incoming XML data into the original business obj.
        List<IDMS_PartnerTradeGroups> chunkPTG = SerializerManager.Deserialize<List<IDMS_PartnerTradeGroups>>(SerializedChunk);

        //[Step-2]
        ////Dummy manipulation of the dataset (Business Logic evaluation).
        List<IDMS_PartnerTradeGroups> lstTarget = new List<IDMS_PartnerTradeGroups>();

        foreach (IDMS_PartnerTradeGroups ptx in chunkPTG)
        {
            lstTarget.Add(ptx);                               
        } 

        ////Add a record with the total value of NumberOfUnits for the partner.
        if (lstTarget.Count > 0)
        {
            decimal? totalUnits = lstTarget.Sum(sx => sx.NumberOfUnits);

            lstTarget.Add(new IDMS_PartnerTradeGroups
                                                                        {
                                                                            PartnerID = Convert.ToInt32(PartnerID),
                                                                            CalendarMonth = 12,
                                                                            CalendarYear = DateTime.Now.Year,
                                                                            NumberOfUnits = totalUnits,
                                                                            PartnerGroupID = "0",
                                                                            TransactionMonth = 1,
                                                                            TransactionYear = DateTime.Now.Year
                                                                        });
        }

        //[Step-3]
        ////Serialize the calculated object into the XML and save it in DB.
        if (lstTarget.Count > 0)
        {
            string targetSerializedXML = SerializerManager.Serialize<List<IDMS_PartnerTradeGroups>>(lstTarget);

            dmxContext.uspSave_IDMS_PartnerTradeGroups_Data(PartnerID, targetSerializedXML, false);

            //[Step-4] Save the Serialized output into REDIS server.
            PersistToRedis(targetSerializedXML, "IDMS_PartnerTradeGroups", MethodBase.GetCurrentMethod().Name, PartnerID, Client);

            //[Step-5]
            //Update the Chunk-Call-Stack status
            lock (_syncLocker)
            {
                UpdateChunkCall((int)Constants.PartnerChunkType.ChunkTypeX, K1JobId, PartnerID);
            }
        }
    }

    private void UpdateChunkCall(int partnerChunkTypeId, int k1JobId, int? partnerId)
    {
        ChunkCallStack currChunkStack = new ChunkCallStack();
        DataModelEntities dmContext = new DataModelEntities();

        currChunkStack = dmContext.ChunkCallStacks.Where(wx => wx.K1JobId == k1JobId
                                                                                    && wx.PartnerId == partnerId
                                                                                    && wx.ReadyToRetire == false
                                                                                    && wx.PartnerChunkTypeId == partnerChunkTypeId)
                                                                                    .FirstOrDefault<ChunkCallStack>();
        if (currChunkStack != null)
        {
            currChunkStack.ChunkStatus = 20;  ////Completed
            currChunkStack.Message = "Processing Complete";
            currChunkStack.DateUpdated = DateTime.UtcNow;
            currChunkStack.UpdatedBy = "Investor-Service";
            dmContext.Entry(currChunkStack).State = System.Data.Entity.EntityState.Modified;
            dmContext.SaveChanges();
        }
    }

public void ProcessChunkStageY()  //IDMS_PartnerTradeGroupTimeLine 
    {
        //[Step-1]
        List<IDMS_PartnerTradeGroupTimeLine> chunkPTG = SerializerManager.Deserialize<List<IDMS_PartnerTradeGroupTimeLine>>(SerializedChunk);

        //[Step-2]
        ////Dummy manipulation of the dataset (Business Logic evaluation).            
        List<IDMS_PartnerTradeGroupTimeLine> lstTarget = new List<IDMS_PartnerTradeGroupTimeLine>();

        foreach (IDMS_PartnerTradeGroupTimeLine ptx in chunkPTG)
        {
            lstTarget.Add(ptx);

        }

        ////Add a record with the total value of NumberOfUnits for the partner.

        if (lstTarget.Count > 0)
        {
            decimal totalUnits = lstTarget.Sum(sx => sx.NumberOfUnits);

            lstTarget.Add(new IDMS_PartnerTradeGroupTimeLine
            {
                PartnerID = Convert.ToInt32(PartnerID),
                CalcMonth = 12,
                CalcYear = DateTime.Now.Year,
                NumberOfUnits = totalUnits,
                TradeGroup = "Total",
                TradeMonth = 12,
                TradeYear = DateTime.Now.Year
            });
        }

        //[Step-3]
        ////Serialize the calculated object into the XML and save it in DB.
        if (lstTarget.Count > 0)
        {
            string targetSerializedXML = SerializerManager.Serialize<List<IDMS_PartnerTradeGroupTimeLine>>(lstTarget);

            DataModelEntities dmxContext = new DataModelEntities();
            dmxContext.uspSave_IDMS_PartnerTradeGroupsTimeline_Data(PartnerID, targetSerializedXML, false);


            //[Step-5]
            //Update the Chunk-Call-Stack status
            lock (_syncLocker)
            {
                UpdateChunkCall((int)Constants.PartnerChunkType.ChunkTypeY, K1JobId, PartnerID);

            }
        }
    }

}

The [Step-5] is giving me lot of trouble. I even added the lock(_locker) block to contain the ORM call but still no luck. Sometimes the data does not get saved into the db due to the concurrency mode =Multiple. The problem occurs randomly and difficult to nail it down.

But when i flip the concurrency Mode=Single, it works like a charm.

I wish to know, what changes should i add to make it work for Multiple concurrency mode. PartnerChunkProcessor is a simple class with the required set of properties, i think its here that the synchronization problem is occurring.

Please advise.

来源:https://stackoverflow.com/questions/42837277/wcf-multiple-concurrency-issue-with-instance-method-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!