函数写入数据库时,它不应该
我有一个间隔为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);
}
从你的代码,我敢肯定,这个程序被调用多次。可能的原因:
- 事件
- 几个地方调用这个独立
放置一个破发点,并观察调用栈的多个abonnement ...
一个想法可能是要么使用要标记的静态标记,由于不活动而注销的过程正在运行并拒绝再次进入该过程。
另一个想法是设置一个值,你lastInputTick
保证,下一次通话将获得低于600的答案...
感谢您的反馈。我没有使用静态标志。你会介意进一步解释它们吗? –
那么,标志总是有点丑,应该避免的东西,但是:当你正在处理强制注销时,我认为在这种情况下这是可以的。在你有''static'GetLastInputTime()'的地方,你可以放置一个'public static bool ForcedShutdown'。当你检查了'> = 600'后输入你的代码块时,你可以将这个标志设置为true。在你的'GetLastInputTime'中,你使用'if(ForcedShutdown)return 0;'。您可以在'finally'块中将其设置为false来处理可能的错误... – Shnugo
感谢您的回应和帮助。我会尽快对此进行测试。 –
最好的办法是进行调试,把一个破发点上插入到数据库并看看它是否被调用3次。你的函数可能会在不同的线程上调用。 –
只是可能性:你是否订阅过3次定时器事件? – 2016-07-15 13:53:05
谢谢你们,我现在回家后会进行调试。不,我只将计时器连接到事件一次。 –