2016-07-15 53 views
1

我有一個間隔爲1秒的計時器。我每秒都會調用這個函數來檢查操作系統的最後輸入時間。如果函數返回的時間超過600(10分鐘),我會調用另一個函數將內容寫入數據庫。函數寫入數據庫時​​,它不應該

問題出現在這裏,而不是插入一行到數據庫中,該函數將在同一秒內創建許多記錄。我不知道爲什麼會發生這種情況。調試時不會發生這種情況。

public void elapsedGetIdleCount(object source, ElapsedEventArgs e) 
    { 
     uint result = GetLastInputTime(); 

     if (result >= 600) 
     { 
      result = 0; 
      tmrIdle.Stop(); 

      try 
      { 
       XmlDocument xDoc = new XmlDocument(); 
       xDoc.Load(@"C:/Users/" + Environment.UserName + "/AppData/Roaming/3CXPhone for Windows/3CXPhone.xml"); 
       var element = xDoc.SelectSingleNode("Accounts/Profiles/Profile/AuthUser"); 
       var extension = element.InnerText.ToString(); 

       SetQueueStatus("LoggedOUT", "Inactivity"); 

       DialogResult mb = MessageBox.Show("You have been Logged Out of the Queues due to inactivity!", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 

       if (mb == DialogResult.OK) 
       { 
        ChangeQueueStatusColor(); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 
    } 

public void SetQueueStatus(string status, string eventDesc) 
    { 
     try 
     { 
      XmlDocument xDoc = new XmlDocument(); 
      xDoc.Load(@"C:/Users/" + Environment.UserName + "/AppData/Roaming/3CXPhone for Windows/3CXPhone.xml"); 
      var element = xDoc.SelectSingleNode("Accounts/Profiles/Profile/AuthUser"); 
      var extension = element.InnerText.ToString(); 

      string conString = "Data Source = lewcomp1\\COMPLIANCE; Initial Catalog = ComplianceData; Integrated Security = True"; 

      using (SqlConnection myCon = new SqlConnection(conString)) 
      { 
       using (SqlCommand myCMD = new SqlCommand()) 
       { 
        myCMD.Connection = myCon; 
        myCMD.CommandText = "UPDATE eData SET QueueStatus = '" + status + "', Extension = '" + extension + "' WHERE UserName LIKE '" + lblUserName.Text + "';"; 
        SqlDataReader myReader; 

        myCon.Open(); 
        myReader = myCMD.ExecuteReader(); 
        myReader.Read(); 
        myCon.Close(); 

        myCMD.CommandText = "INSERT INTO eQueueData (Date_Time, UserName, Extension, EventID, EventDesc) VALUES ('" + DateTime.Now + "','" + lblUserName.Text + "','" + extension + "','" + status + "','" + eventDesc + "');"; 
        myCon.Open(); 
        myReader = myCMD.ExecuteReader(); 
        myReader.Read(); 
        myCon.Close(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

static uint GetLastInputTime() 
    { 
     uint idleTime = 0; 
     LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); 
     lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); 
     lastInputInfo.dwTime = 0; 

     uint envTicks = (uint)Environment.TickCount; 

     if (GetLastInputInfo(ref lastInputInfo)) 
     { 
      uint lastInputTick = lastInputInfo.dwTime; 

      idleTime = envTicks - lastInputTick; 
     } 
     return ((idleTime > 0) ? (idleTime/1000) : 0); 
    } 

Screen Shot of DB Entries

+1

最好的辦法是進行調試,把一個破發點上插入到數據庫並看看它是否被調用3次。你的函數可能會在不同的線程上調用。 –

+0

只是可能性:你是否訂閱過3次定時器事件? – 2016-07-15 13:53:05

+0

謝謝你們,我現在回家後會進行調試。不,我只將計時器連接到事件一次。 –

回答

0

從你的代碼,我敢肯定,這個程序被調用多次。可能的原因:

  • 事件
  • 幾個地方調用這個獨立

放置一個破發點,並觀察調用棧的多個abonnement ...

一個想法可能是要麼使用要標記的靜態標記,由於不活動而註銷的過程正在運行並拒絕再次進入該過程。

另一個想法是設置一個值,你lastInputTick保證,下一次通話將獲得低於600的答案...

+0

感謝您的反饋。我沒有使用靜態標誌。你會介意進一步解釋它們嗎? –

+0

那麼,標誌總是有點醜,應該避免的東西,但是:當你正在處理強制註銷時,我認爲在這種情況下這是可以的。在你有''static'GetLastInputTime()'的地方,你可以放置一個'public static bool ForcedShutdown'。當你檢查了'> = 600'後輸入你的代碼塊時,你可以將這個標誌設置爲true。在你的'GetLastInputTime'中,你使用'if(ForcedShutdown)return 0;'。您可以在'finally'塊中將其設置爲false來處理可能的錯誤... – Shnugo

+0

感謝您的迴應和幫助。我會盡快對此進行測試。 –