Hello everyone,
I have a problem and i need help in something,
I am developing a software based on c#.net that will generate a QR ticket through and EPSON printer, and that ticket is supposed to be in enrolled a 3 ZKteco access control panel to be used only one time and the ticket will get removed from the whitelist of the ZKteco access control panels.
The problem is that the tasks was overlapping, so i used the lock feature which fixed the overlapping a little bit, the time of the tasks are no longer deterministic.
I need help how to get out this, also i had an idea but i don't know how to implement it which was to create a thread scheduler which will prevent overlapping and when the task is triggered to run it will be added to a FIFO queue and the task manager will run the task from it accordingly
What I have tried:
so i mainly have 2 tasks;
1- Generate Ticket and Enroll user to access control
2- Check logs and if enrolled tickets are used remove them
Task 1 is initiate when the user presses a button by the following implementation,
private void button7_Click(object sender, EventArgs e)
{
{
Generated_tickets_Counter.Increment();
Visitor.Generate_Ticket(Visitor.Generate_VisitorID(Generated_tickets_Counter.Count));
pictureBox6.Image = Visitor.QRcodeImage;
Printer = new TicketPrinter("جمعية الهلال الأحمر", Visitor.complete_zeros(Generated_tickets_Counter.Count.ToString(), 3), Visitor.QRcodeImage);
var item = GetItem(Visitor);
IDbuffer = item.Value;
var ips = DB_Handler.GetIPlist();
Pins.Add(Generated_tickets_Counter.Count.ToString());
timer1.Enabled = true;
System.Threading.Thread t = new Thread(x => EnrollIps(ips, item));
t.Start();
}
}
private void EnrollIps(List<string> ips, KeyValuePair<int, string> item)
{
lock (mutex)
{
foreach (var ip in ips)
{
ACManager.Connect(ip, "4370");
ACManager.EnrollUser(item.Key.ToString(), item.Value);
ACManager.Disconnect();
}
var dlgt = new dlgtAfterEnrollIps(AfterEnrollIps);
this.Invoke(dlgt, new object[] { item.Key, item.Value });
}
}
private void AfterEnrollIps(int key , string value)
{
Printer.Print_Ticket();
label_counter.Text = Visitor.complete_zeros(Generated_tickets_Counter.Count.ToString(), 3);
DateTime current_datetime = DateTime.Now;
if (Generated_tickets_Counter.Count == 1)
{
DB_Handler.Add_log(current_datetime.ToShortDateString(), Username, Generated_tickets_Counter.Count.ToString(), "0");
}
if (Generated_tickets_Counter.Count > 1)
{
DB_Handler.Update_GenTickets(Generated_tickets_Counter.Count.ToString(), current_datetime.ToShortDateString());
}
AccessControl._values.Add(key, value);
label_status.Text = "Visitor Successfully Created";
DB_Handler.Add_Ticket(IDbuffer, Username);
}
and Task2 periodic every 12s
private void timer1_Tick(object sender, EventArgs e)
{
System.Threading.Thread t = new Thread(x => handleTimer());
t.Start();
}
private void handleTimer()
{
var ips = DB_Handler.GetIPlist();
DateTime current_datetime = DateTime.Now;
foreach (var ip in ips)
{
var logs = new List<LogItem>();
lock (mutex)
{
ACManager.Connect(ip, "4370");
logs = ACManager.GetLogs(false);
ACManager.Disconnect();
}
foreach (var user in AccessControl._values)
{
if (logs.Any(x => x.Pin == user.Key && x.Cardno == Convert.ToInt64(user.Value)))
{
var items = logs.Where(x => x.Pin == user.Key);
foreach (var address in ips)
{
lock (mutex)
{
ACManager.Connect(address, "4370");
ACManager.RemoveUser(user.Key.ToString());
ACManager.Disconnect();
}
}
Used_tickets_Counter.Increment();
DB_Handler.Remove_ticket(user.Value.ToString(), Username);
DB_Handler.Update_UsedTickets(Used_tickets_Counter.Count.ToString(), current_datetime.ToShortDateString());
break;
}
}
}
var dlgt = new dlgtAfterHandleTimer(AfterHandleTimer);
this.Invoke(dlgt);
}