I
Ivan
Hi there
My work on threads continues with more or less success. Here is what I'm
trying to do:
Class JobAgent is incharged for some tasks and when it's called it starts
thread which performs the job. Application contains one list of agents
that are idle at the moment and list of busy agents. In loop it checks if
there
are agents in idle list and if there are some, it starts them.
I'm using events from JobAgent class to notify main thread in order to
update
lists. Problem is that I'm not sure that I use locks at right places and I
have
a problem to understand what it is happening when of the threads fire event
and
code in main thread is called (agent thread is interrupting main thread and
start
execution of event handler - fogy at the moment). Am I missing
synchronization
in that context?
Thx. in advance
Best regards
Ivan
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Diagnostics;
namespace Threads
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmMain : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStartThreads;
protected ArrayList idleAgents = new ArrayList ();
protected ArrayList busyAgents = new ArrayList ();
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartThreads = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStartThreads
//
this.btnStartThreads.Location = new System.Drawing.Point(48, 48);
this.btnStartThreads.Name = "btnStartThreads";
this.btnStartThreads.Size = new System.Drawing.Size(88, 23);
this.btnStartThreads.TabIndex = 0;
this.btnStartThreads.Text = "&Start threads";
this.btnStartThreads.Click += new
System.EventHandler(this.btnStartThreads_Click);
//
// frmMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(176, 125);
this.Controls.Add(this.btnStartThreads);
this.Name = "frmMain";
this.Text = "Thread test";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new frmMain());
}
private void btnStartThreads_Click(object sender, System.EventArgs e)
{
// create job agents and put them in idleAgents list
for (int c = 0;c < 5;c++)
{
JobAgent agent = new JobAgent ();
agent.AgentFinished +=new
JobAgentNotificationEventHandler(agent_AgentFinished);
agent.AgentStarted +=new
JobAgentNotificationEventHandler(agent_AgentStarted);
idleAgents.Add (agent);
}
// check if there are agents in idleAgents list and start them
while (true)
{
if (idleAgents.Count > 0)
((JobAgent)idleAgents[0]).Start ();
}
}
// called when agent finished
private void agent_AgentFinished(JobAgent jobAgent)
{
// move agent from busyAgents in to idleAgents
busyAgents.Remove (jobAgent);
idleAgents.Add (jobAgent);
}
// called when agent started
private void agent_AgentStarted(JobAgent jobAgent)
{
// move agent from idleAgents in to busyAgents
busyAgents.Add (jobAgent);
idleAgents.Remove (jobAgent);
}
}
public delegate void JobAgentNotificationEventHandler (JobAgent jobAgent);
public class JobAgent
{
private bool isBusy = false;
private Object busyLock = new Object ();
private static Object eventLock = new Object ();
protected Thread thread = null;
public event JobAgentNotificationEventHandler AgentStarted = null;
public event JobAgentNotificationEventHandler AgentFinished = null;
public void Start ()
{
lock (busyLock)
{
if (isBusy == true)
return;
else
isBusy = true;
}
thread = new Thread (new ThreadStart (this.Run));
thread.Start ();
// fire event that thread is starting
lock (eventLock)
{
if (AgentStarted != null)
AgentStarted (this);
}
}
public void Run ()
{
Random rnd = new Random ();
Debug.WriteLine ("Thread num. " + Convert.ToString
(Thread.CurrentThread.GetHashCode ()) + " started");
Thread.Sleep (2000 + rnd.Next (5)*1000);
Debug.WriteLine ("Thread num. " + Convert.ToString
(Thread.CurrentThread.GetHashCode ()) + " finished");
lock (busyLock)
{
isBusy = false;
}
lock (eventLock)
{
if (AgentFinished != null)
AgentFinished (this);
}
}
}
}
My work on threads continues with more or less success. Here is what I'm
trying to do:
Class JobAgent is incharged for some tasks and when it's called it starts
thread which performs the job. Application contains one list of agents
that are idle at the moment and list of busy agents. In loop it checks if
there
are agents in idle list and if there are some, it starts them.
I'm using events from JobAgent class to notify main thread in order to
update
lists. Problem is that I'm not sure that I use locks at right places and I
have
a problem to understand what it is happening when of the threads fire event
and
code in main thread is called (agent thread is interrupting main thread and
start
execution of event handler - fogy at the moment). Am I missing
synchronization
in that context?
Thx. in advance
Best regards
Ivan
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Diagnostics;
namespace Threads
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmMain : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStartThreads;
protected ArrayList idleAgents = new ArrayList ();
protected ArrayList busyAgents = new ArrayList ();
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartThreads = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStartThreads
//
this.btnStartThreads.Location = new System.Drawing.Point(48, 48);
this.btnStartThreads.Name = "btnStartThreads";
this.btnStartThreads.Size = new System.Drawing.Size(88, 23);
this.btnStartThreads.TabIndex = 0;
this.btnStartThreads.Text = "&Start threads";
this.btnStartThreads.Click += new
System.EventHandler(this.btnStartThreads_Click);
//
// frmMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(176, 125);
this.Controls.Add(this.btnStartThreads);
this.Name = "frmMain";
this.Text = "Thread test";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new frmMain());
}
private void btnStartThreads_Click(object sender, System.EventArgs e)
{
// create job agents and put them in idleAgents list
for (int c = 0;c < 5;c++)
{
JobAgent agent = new JobAgent ();
agent.AgentFinished +=new
JobAgentNotificationEventHandler(agent_AgentFinished);
agent.AgentStarted +=new
JobAgentNotificationEventHandler(agent_AgentStarted);
idleAgents.Add (agent);
}
// check if there are agents in idleAgents list and start them
while (true)
{
if (idleAgents.Count > 0)
((JobAgent)idleAgents[0]).Start ();
}
}
// called when agent finished
private void agent_AgentFinished(JobAgent jobAgent)
{
// move agent from busyAgents in to idleAgents
busyAgents.Remove (jobAgent);
idleAgents.Add (jobAgent);
}
// called when agent started
private void agent_AgentStarted(JobAgent jobAgent)
{
// move agent from idleAgents in to busyAgents
busyAgents.Add (jobAgent);
idleAgents.Remove (jobAgent);
}
}
public delegate void JobAgentNotificationEventHandler (JobAgent jobAgent);
public class JobAgent
{
private bool isBusy = false;
private Object busyLock = new Object ();
private static Object eventLock = new Object ();
protected Thread thread = null;
public event JobAgentNotificationEventHandler AgentStarted = null;
public event JobAgentNotificationEventHandler AgentFinished = null;
public void Start ()
{
lock (busyLock)
{
if (isBusy == true)
return;
else
isBusy = true;
}
thread = new Thread (new ThreadStart (this.Run));
thread.Start ();
// fire event that thread is starting
lock (eventLock)
{
if (AgentStarted != null)
AgentStarted (this);
}
}
public void Run ()
{
Random rnd = new Random ();
Debug.WriteLine ("Thread num. " + Convert.ToString
(Thread.CurrentThread.GetHashCode ()) + " started");
Thread.Sleep (2000 + rnd.Next (5)*1000);
Debug.WriteLine ("Thread num. " + Convert.ToString
(Thread.CurrentThread.GetHashCode ()) + " finished");
lock (busyLock)
{
isBusy = false;
}
lock (eventLock)
{
if (AgentFinished != null)
AgentFinished (this);
}
}
}
}