Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi,
Really,i got frustrated ,I don't know what is going wrong.

In my application ,I have one timer which invoke a method based on 1 second interval.

In that method ,i will read one row from table,if that table contains expected records,then i will do some operations.

C#
DataTable dtStationCode = new DataTable();
           string LocalStationCode = "";
           try
           {
               oDataParamBLL = new DataParametersBLL();
               oDataParamBLL.Mode = "SELECT_STATIONCODE";
               oDataParamBLL.LineCode = Global.LineCode;
               oDataParamBLL.OperationCode = Global.OperationCode;
               dtStationCode = oServerperformBLL.GetStationCode(oDataParamBLL);
               if (dtStationCode != null)
               {
                   if (dtStationCode.Rows.Count > 0)
                   {
                       foreach (DataRow dr in dtStationCode.Rows)
                       {
                           log.Info("Data Table Row Value Station Code : "+dr[0].ToString());
                       }
                       LocalStationCode = dtStationCode.Rows[0]["StationCode"].ToString();
                       dtStationCode = null;
                   }
                   else
                   {
                       log.Fatal("Station Code not Available on Assy_Stations_Jig_In_Out_Status Table");
                   }
               }


but when i try to read data from that table ,some times i got an exception

"Column StationCode does not belong to the table"
but I'm getting the exception some time only,If i restart the application it is working fine. after sometime same exception is coming.


I'm suspecting my timer is behaving something wrong.please suggest me if anything wrong.

What I have tried:

C#
timerToMonitorExcel = new System.Timers.Timer();
timerToMonitorExcel.Enabled = true;
timerToMonitorExcel.Start();
log.Info("Timer Started");
timerToMonitorExcel.Interval = 1000;
timerToMonitorExcel.Elapsed +=new System.Timers.ElapsedEventHandler(timerToMonitorExcel_Elapsed);



C#
static object LocktimerToMonitorExcel_Elapsed = new object();
      Dictionary<string, string> dictParams = new Dictionary<string, string>();
      void timerToMonitorExcel_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
      {
          Monitor.Enter(LocktimerToMonitorExcel_Elapsed);
          try
          {
              GetJigStatus();

          }
          catch (Exception ex)
          {
              log.Error("Issue on Excel Data ", ex);
          }
          finally
          {

              Monitor.Exit(LocktimerToMonitorExcel_Elapsed);
          }
      }
Posted
Updated 12-May-16 2:00am
v4
Comments
Richard Deeming 7-May-16 6:25am    
Is the first code block from the GetJigStatus method?

And what does the GetStationCode method look like?
King Fisher 9-May-16 2:02am    
GetJigStatus method will invoke 3 methods, GetStationCode is the one of the method.

You can try the following things to analyze your problem.

1. Disable the timer when you enter the Timer.Elapsed event method.
This will prevent an event to be fired during the execution of the event method.

2. Add a Stopwatch in order to see how long time you spend in there.

C#
void timerToMonitorExcel_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    try
    {
        timerToMonitorExcel.Enabled = false;
        GetJigStatus();
    }
    catch (Exception ex)
    {
        log.Error("Issue on Excel Data ", ex);
    }
    finally
    {
        Debug.WriteLine(sw.ElapsedMilliseconds);
        timerToMonitorExcel.Enabled = true;
    }
}


This will give you two things:
1. A confirmation of if the problem is events fired too fast for your code.
2. The time you spend in the method.

If the time you spend is longer than 1 sec, and you cannot make the interval longer, you have to make your code more efficient.
 
Share this answer
 
Comments
King Fisher 9-May-16 2:06am    
thanks,Let me check this.
King Fisher 9-May-16 2:30am    
Actually ,I would like to know why it is behaving like this. even though i have lock statement on every methods.
George Jonsson 9-May-16 4:28am    
The Monitor class only blocks other threads. It is OK for the same thread to call Monitor.Enter multiple times without being blocked.
Here I guess it is the same thread that calls the method every time.
King Fisher 9-May-16 4:51am    
thank you. yes, It is . the exception says "the column name doesn't belongs to that table". some how dtStationCode having some values ,but it is not null. i didn't use that object anywhere outside the method, then how it can hold some other values? even though if the same thread access the method ,it should have the values which should match the column name.
George Jonsson 9-May-16 20:22pm    
If the first call is trying to executing this line:
LocalStationCode = dtStationCode.Rows[0]["StationCode"].ToString();
and the second call just entered the method and executes this line:
DataTable dtStationCode = new DataTable();

Then it makes sense that you get the error "the column doesn't belong to that table"
If your code works fine when launch manually, but fails sometime when fired by timer, you probably face a race condition.

Advice measure the time needed to run your method. The closer to 1 seconde you will be, to higher you will be at risk of race condition.
Consider also that the server will be occupied from time to time with updating the database which may increase the method runtime.
 
Share this answer
 
Comments
King Fisher 10-May-16 4:39am    
its taking maximum 10 milliseconds only.
First of all, the timer interval 1 second is very less to perform big operations, try to increase the interval and check.
the below code will fix the error but you will have find the real real behind it.
C#
if ( dtStationCode.Columns.Contains("StationCode"))
          LocalStationCode = dtStationCode.Rows[0]["StationCode"].ToString();
 
Share this answer
 
Comments
King Fisher 7-May-16 5:02am    
but I cant increase the time interval. Is there any other way to track it. ?
Karthik_Mahalingam 7-May-16 5:05am    
I am not sure about it.
you can try using infinite loop with 1 second delay as System.Threading.Thread.Sleep(1000);
in case if there is no operation apart from this, in your application..
Santosh Kokatnur 7-May-16 5:14am    
Deleted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900