Hello World,
I am facing an unusual behaviour in my code with (most probably) BeginInvoke. I have a login form on which an ID is generated each time user tries to login, the ID authorization is written to a file, which login form is watching using FileSystemWatcher. On authorization an event is generated which is captured by main form.
Now my issue is that old IDs show up at the time of verification, even though each time a new instance of LoginForm in created at the time of login process. First time the ID value in strID variable is correct but from then on for each consecutive login, previous IDs show up.
It is difficult for me to explain it in words correctly, so I am attaching the code for login form. The weird behaviour I am facing is at
if(arrData[0] == this.strID)
part of GetAuthorizationStatus function. Please help me understand whether this is an expected behaviour or am I doing something wrong here.
Login form have 3 buttons : btnLogin for getting the ID, btnExit to exit the form and btnAuth for authenticating (I have put it here for testing, instead of another app/service)
Following is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace SampleInvokeTest
{
public static class IDGenerator
{
private static int iCurrentID;
static IDGenerator()
{
iCurrentID = 0;
}
public static int GetNewID()
{
return ++iCurrentID;
}
}
public class AuthEventArgs : EventArgs
{
private string strID;
private DateTime dtLoginAt;
private bool isAuthorized;
public AuthEventArgs(string ID, DateTime LoginAt, bool isAuthorized)
{
this.strID = ID;
this.dtLoginAt = LoginAt;
this.isAuthorized = isAuthorized;
}
public string ID
{
get{ return this.strID; }
}
public DateTime LoginAt
{
get{ return this.dtLoginAt; }
}
public bool IsAuthorized
{
get{ return this.isAuthorized; }
}
}
public partial class LoginForm : Form
{
delegate void ShowDelegate();
private string strID;
private const string FILE_PATH = @"E:\test.txt";
private DateTime dtLastResultReadTime = DateTime.MinValue;
private DateTime dtLoginAt = DateTime.MinValue;
private bool isAuthorized = false;
private string strLoginErrorMessage ="";
public event EventHandler<AuthEventArgs> AuthOccurred;
public LoginForm()
{
InitializeComponent();
FileSystemWatcher fswAuth = new FileSystemWatcher(Path.GetDirectoryName(FILE_PATH));
fswAuth.Filter = Path.GetFileName(FILE_PATH);
fswAuth.NotifyFilter = NotifyFilters.LastWrite;
fswAuth.Changed+= new FileSystemEventHandler(fswAuth_Changed);
fswAuth.EnableRaisingEvents = true;
tmrTimeout.Interval = 5000;
tmrTimeout.Tick+= new EventHandler(tmrTimeout_Tick);
this.strID = "";
}
void fswAuth_Changed(object sender, FileSystemEventArgs e)
{
DateTime dtTempReadAt = File.GetLastWriteTime(FILE_PATH);
if (dtLastResultReadTime < dtTempReadAt)
{
dtLastResultReadTime = dtTempReadAt;
GetAuthorizationStatus();
}
}
private void GetAuthorizationStatus()
{
if (InvokeRequired)
{
BeginInvoke(new ShowDelegate(GetAuthorizationStatus));
}
else
{
string strData = ",";
tmrTimeout.Enabled = false;
using (FileStream stream = new FileStream(FILE_PATH, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader streamReader = new StreamReader(stream))
{
try
{
strData = streamReader.ReadToEnd();
}
catch (Exception)
{
}
}
}
string[] arrData = strData.Split(new char[] { ',' });
if (arrData.Length == 2)
{
if(arrData[0] == this.strID)
{
if (arrData[1] == "Y")
{
tmrTimeout.Enabled = false;
this.lblWait.Visible = false;
this.btnExit.Enabled = true;
this.btnLogin.Enabled = false;
this.isAuthorized = true;
this.strLoginErrorMessage = "";
onAuthOccurred(new AuthEventArgs(this.strID, this.dtLoginAt, this.isAuthorized));
this.Close();
}
else
{
tmrTimeout.Enabled = false;
this.lblWait.Visible = false;
this.btnExit.Enabled = true;
this.btnLogin.Enabled = true;
this.strID = "";
this.dtLoginAt = DateTime.MinValue;
this.isAuthorized = false;
this.strLoginErrorMessage = "Authorization denied.";
}
}
}
if (!this.isAuthorized && this.strLoginErrorMessage != "")
{
MessageBox.Show(this.strLoginErrorMessage, "Authorization denied", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
void tmrTimeout_Tick(object sender, EventArgs e)
{
tmrTimeout.Enabled = false;
this.lblWait.Visible = false;
this.btnExit.Enabled = true;
this.btnLogin.Enabled = true;
this.strID="";
this.isAuthorized = false;
this.dtLoginAt = DateTime.MinValue;
MessageBox.Show("Timeout occurred while waiting for authorization.", "Authorization timeout", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void onAuthOccurred(AuthEventArgs e)
{
EventHandler<AuthEventArgs> handler = AuthOccurred;
if (handler != null)
{
handler(this, e);
}
}
private void btnLogin_Click(object sender, EventArgs e)
{
this.dtLoginAt = DateTime.Now;
this.strID = IDGenerator.GetNewID().ToString();
this.btnLogin.Enabled = false;
this.btnExit.Enabled = false;
tmrTimeout.Enabled = true;
lblWait.Visible = true;
}
private void btnExit_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Do you wish to cancel login?", "Cancel Login", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
this.strID="";
this.isAuthorized = false;
this.dtLoginAt = DateTime.MinValue;
onAuthOccurred(new AuthEventArgs(this.strID, this.dtLoginAt, this.isAuthorized));
this.Close();
}
}
void BtnAuthClick(object sender, EventArgs e)
{
File.WriteAllText(FILE_PATH,string.Format("{0},Y",this.strID));
}
}
}