2016-07-15 16 views
1

私は1秒間隔のタイマーを持っています。毎秒、私はこの機能をOSの最後の入力時間をチェックするために呼びます。関数が返す時間が600(10分)を超えている場合は、DBに書き込む別の関数を呼び出します。機能DBに書き込みません。

DBに1つの行を挿入するのではなく、同じ秒内に多数のレコードが作成されるという問題がここにあります。なぜこれが起こっているのか分かりません。デバッグ時には発生しません。

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

...次のコールが600以下の答えを得るだろうことを、確認してくださいlastInputTickに値を設定することでしたし、DBへの挿入にブレークポイントを置きますそれが3回呼び出されるかどうかを確認します。あなたの関数は別のスレッドで呼び出すことができます。 –

+0

ただ可能性:経過したタイマーイベントを3回購読していますか? –

+0

ありがとう、私は今家に帰るときにデバッグします。いいえ、私はイベントに一度だけタイマーを付けました。 –

答えて

0

あなたのコードから、私は、このルーチンが複数回呼び出されることを、かなり確信しています。考えられる理由:

  • イベント
  • いくつかの場所の複数のabonnementプレイスブレークポイントを

独立して、これを呼び出し、コールスタックを観察...

ひとつのアイデアは、どちらかを使用するかもしれませんアクティブでないためにログアウトするプロセスが実行中であり、プロシージャに再び入ることを拒否する静的フラグ。

もう一つのアイデアは、あなたの最善の策は、デバッグにある

+0

フィードバックいただきありがとうございます。私は静的フラグを使用していません。それをさらに説明してもらえますか? –

+0

さて、フラグは常に醜いものですが、避けなければならないものはありますが、強制ログアウトを処理しているので、この場合はOKです。 'static uint GetLastInputTime()'があるところで、 'public static bool ForcedShutdown'を置くことができます。 '> = 600'をチェックした後にコードブロックを入力すると、このフラグがtrueに設定されます。あなたの 'GetLastInputTime'では' if(ForcedShutdown)return 0; 'のようなものを使います。考えられるエラーに対処するために 'finally'ブロックでこれをfalseに設定するかもしれません... – Shnugo

+0

お返事ありがとうございました。できるだけ早くこれをテストします。 –

関連する問題