Vb.net 在设定的时间限制内禁用表单控件,以防止逻辑错误

Vb.net 在设定的时间限制内禁用表单控件,以防止逻辑错误,vb.net,winforms,ms-access,controls,Vb.net,Winforms,Ms Access,Controls,在我的程序中,有一个“注销”选项,用于将当前用户注销系统并返回登录屏幕,而不仅仅是退出整个程序 我已经在注销时正确更新了数据库,但是,当主窗体关闭并返回登录屏幕时,有一个轻微的逻辑错误 当我输入用户名和密码,然后按“登录”和“继续”时,将显示一个消息框,显示当前用户已登录。这是我实现的一个特性,但此时不应该显示消息 在逐步检查并检查数据库后,用户已正确注销,但数据库更新速度似乎不够快,因此它认为用户仍在登录 例如: 我以测试用户“User1”的身份登录。用户名和密码都是“1” 我注销,代码执行

在我的程序中,有一个“注销”选项,用于将当前用户注销系统并返回登录屏幕,而不仅仅是退出整个程序

我已经在注销时正确更新了数据库,但是,当主窗体关闭并返回登录屏幕时,有一个轻微的逻辑错误

当我输入用户名和密码,然后按“登录”和“继续”时,将显示一个
消息框
,显示当前用户已登录。这是我实现的一个特性,但此时不应该显示消息

在逐步检查并检查数据库后,用户已正确注销,但数据库更新速度似乎不够快,因此它认为用户仍在登录

例如:

我以测试用户“User1”的身份登录。用户名和密码都是“1”

我注销,代码执行

在登录屏幕上,我使用以下按键模式: 1+TAB+1在相关文本框中输入1的用户名和密码。 然后,我使用Enter+Enter来触发登录和继续按钮的按钮单击事件

总而言之,这可能需要一秒钟,最多2秒钟

但是,这会触发消息框,提示用户已登录

然而,如果我只是输入用户名/密码,然后在按下“登录”按钮前等待几秒钟,那么它工作正常-因此数据库没有时间更新是问题所在

那么,有没有一种方法可以在一两秒钟内禁用表单控件的登录,从而使数据库有机会提交更改

基本上有两种方法可以做到这一点

  • 我可以将主窗体关闭延迟2秒钟,然后再关闭/显示登录窗体(尝试使用
    应用程序.DoEvents
    子例程,但登录窗体仍然显示,因为它始终在后台打开

  • 或者,只显示一个等待光标,但当它聚焦时禁用文本框2秒钟

注销过程的代码:

sql = "UPDATE [System Settings] SET usersOnline = ?"
Dim cmd As New OleDbCommand(sql, con)
cmd.Parameters.Add("@users", OleDbType.VarChar).Value = users
cmd.ExecuteNonQuery()

Try
  sql = "UPDATE [Users] SET [isOnline] = ? WHERE User_ID = ?"
  Dim update As New OleDb.OleDbCommand(sql, con)
  update.Parameters.Add("@isOn", OleDb.OleDbType.Boolean).Value = False
  update.Parameters.Add("@ID", OleDb.OleDbType.VarChar).Value = user
  update.ExecuteNonQuery()
Catch
End Try
登录按钮代码:

For Each userRow In mainDBset.Tables(0).Rows
  If userRow.Item("User_ID") = txtUser.Text And userRow.Item("Password") = txtPw.Text Then

    If usersOnline >= maxUsers Then
      MsgBox("Unable to log in, max user limit of '" & maxUsers.ToString & "' has been reached - '" & usersOnline & "' currently logged on.", MsgBoxStyle.OkOnly, "Max User Limit Reached")
      Exit Sub
    End If

    sql = "SELECT * FROM [Users] WHERE [User_ID] = ?"
    Dim checkCMD As New OleDb.OleDbCommand(sql, mainDBconnection)
    Dim checkAdapter As New OleDb.OleDbDataAdapter(checkCMD)
    checkAdapter.SelectCommand.Parameters.Add("@ID", OleDb.OleDbType.VarChar).Value = txtUser.Text
    Dim cDt As New DataTable
    Dim cDs As New DataSet
    checkAdapter.Fill(cDs)
    cDt = cDs.Tables(0).Copy()

    If cDt.Rows(0).Item("isOnline") = True Then
       MessageBox.Show("This user is already logged into the system, so cannot be logged in again.", "Error Logging On", MessageBoxButtons.OK)
       Exit Sub
    End If
我解决了这个问题

问题是因为我在显示主窗体时隐藏了登录窗体,所以当主窗体关闭时,登录窗体仍然使用与关闭时相同的连接、相同的值、属性等

这意味着即使使用空白文本框,用户也可以直接再次登录

为了解决这个问题,我在关闭表单时处理了连接,然后在继续按钮单击事件中调用
.ShowDialog()
后重置值并重新加载表单


进行了大量调试,不容易解释,但关闭连接并将表单重新加载到原始状态基本上解决了问题。

Hmmm…我从未听说过出现这种情况,并且数据库数据没有及时更新…您是否可以关闭连接,然后在日志关闭后重新打开它关于表单加载?@David谢谢你的建议,但是我已经尝试过了,数据库仍然说用户已经登录。我真的需要一个延迟来阻止它。所以要说清楚,你是说对更新函数的调用在更新完成之前返回吗?发布附加到两个按钮上的代码。这s听起来不正确。@peterG是的,当窗体关闭,我再次尝试登录时,如果我不等待几秒钟,数据库仍会返回用户已登录的消息