Click here to Skip to main content
15,918,267 members
Home / Discussions / C#
   

C#

 
GeneralSearch Pin
vuthaianh22-Apr-05 23:33
vuthaianh22-Apr-05 23:33 
GeneralRe: Search Pin
Polis Pilavas23-Apr-05 5:32
Polis Pilavas23-Apr-05 5:32 
GeneralRe: Search Pin
Anonymous24-Apr-05 1:44
Anonymous24-Apr-05 1:44 
GeneralRe: Search Pin
vuthaianh24-Apr-05 13:16
vuthaianh24-Apr-05 13:16 
GeneralFile/Folder properties for multiple files Pin
Anonymous22-Apr-05 17:46
Anonymous22-Apr-05 17:46 
GeneralRe: File/Folder properties for multiple files Pin
leppie22-Apr-05 20:36
leppie22-Apr-05 20:36 
GeneralRe: File/Folder properties for multiple files Pin
Anonymous23-Apr-05 4:22
Anonymous23-Apr-05 4:22 
GeneralThreading Problem Pin
ACorbs22-Apr-05 16:41
ACorbs22-Apr-05 16:41 
I am attempting to write a command queue. It is important that each command is executed in order (FIFO). This command queue will be running functions that will have to interact with controls using Control.Invoke. The problem I am having has to do with threading and is harder to describe then to show. Code Follows:

C#
public struct CommandContainer
{
    public System.Delegate method;
    public object[] parameters;
}


CommandQueue.cs
-------------------------
C#
using System;
using System.Threading;
using System.Windows.Forms;

namespace CommandQueue
{

	public delegate void CommandFunction();
	/// <summary>
	/// Summary description for CommandQueue.
	/// </summary>
	public class CommandQueue:System.Collections.Queue
	{

		private ManualResetEvent m_ManualResetEvent;

		public CommandQueue()
		{
			//m_ManualResetEvent = new ManualResetEvent(true);
		}
	
		public override void Clear()
		{
			lock(this.SyncRoot)
			{
				// TODO:  Add CommandQueue.Clear implementation
				base.Clear ();
			}
		}
	
		public override object Dequeue()
		{
			lock(this.SyncRoot)
			{
				// TODO:  Add CommandQueue.Dequeue implementation
				return base.Dequeue ();
			}
		}
	
		public override object Peek()
		{
			lock(this.SyncRoot)
			{
				// TODO:  Add CommandQueue.Peek implementation
				return base.Peek ();
			}
		}
	
		public override void Enqueue(object obj)
		{
			lock(this.SyncRoot)
			{
				if(obj is CommandContainer)
				{
					base.Enqueue (obj);
				} 
				else
				{
					//TODO: Provide error code here
				}
			}
		}

		public void Enqueue(CommandFunction target)
		{
			lock(this.SyncRoot)
			{
				CommandContainer t_CommandContainer;
				t_CommandContainer.method = target;
				t_CommandContainer.parameters = null;
				base.Enqueue (t_CommandContainer);
			}
		}

		public void Enqueue(System.Delegate method, object[] parameters)
		{
			lock(this.SyncRoot)
			{
				CommandContainer t_CommandContainer;
				t_CommandContainer.method = method;
				t_CommandContainer.parameters = parameters;
				base.Enqueue (t_CommandContainer);
			}
		}

		/// <summary>
		/// Executes all commands in the que
		/// </summary>
		public void Flush()
		{
				Thread t_FlushThread = new Thread(new ThreadStart(FlushThreadStart));
			t_FlushThread.Name = "Flush Thread";
				t_FlushThread.Start();
				t_FlushThread.Join();
		}

		private void FlushThreadStart()
		{
			lock(this.SyncRoot)
			{
				for(int i = 0; i < this.Count; i++)
				{
					//m_ManualResetEvent.WaitOne();
					//m_ManualResetEvent.Reset();
					Thread t_RunThread = new Thread(new ThreadStart(RunCommand));
					t_RunThread.Name = i.ToString() + " : " + ((CommandContainer)base.Peek()).method.Method.ToString();
					t_RunThread.Start();
					t_RunThread.Join(500);
				}
			}
		}

		private void RunCommand()
		{
			object t_Command = base.Dequeue();
			if(t_Command is CommandContainer)
			{
				CommandContainer t_CommandContainer = (CommandContainer)t_Command;
				t_CommandContainer.method.DynamicInvoke(t_CommandContainer.parameters);
			}
			//m_ManualResetEvent.Set();
		}
	}
}


Form1.cs
----------------
C#
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace CommandQueue
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		CommandQueue CQ = new CommandQueue();
		private System.Windows.Forms.Button button1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <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.button1 = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(8, 8);
			this.button1.Name = "button1";
			this.button1.Size = new System.Drawing.Size(72, 40);
			this.button1.TabIndex = 0;
			this.button1.Text = "button1";
			this.button1.Click += new System.EventHandler(this.button1_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(292, 273);
			this.Controls.Add(this.button1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[MTAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		private void button1_Click(object sender, System.EventArgs e)
		{
			for(int i =0; i< 2; i++)
			{
				CQ.Enqueue(new CommandFunction(Fctn0));
				CQ.Enqueue(new CommandFunction(Fctn1));
				CQ.Enqueue(new CommandFunction(Fctn2));
				CQ.Enqueue(new CommandFunction(Fctn3));
			}
			CQ.Flush();
		}

		private void Fctn0()
		{
			Console.WriteLine("0");
		}

		private void Fctn1()
		{
			Console.WriteLine("1A");
			this.button1.Invoke(new CommandFunction(foo));
			Console.WriteLine("1B");
		}

		private void Fctn2()
		{
			Console.WriteLine("2");
		}

		private void Fctn3()
		{
			Console.WriteLine("3");
		}

		private void foo()
		{
			//Code where invoke is required
			//this.button1.Width+=5;
			Console.WriteLine("Foo invoked from Fctn1");
		}
	}
}


OUTPUT:
The thread '0 : Void Fctn0()' (0x5f0) has exited with code 0 (0x0).
0
1A
The thread '2 : Void Fctn2()' (0x878) has exited with code 0 (0x0).
2
3
The thread '3 : Void Fctn3()' (0x894) has exited with code 0 (0x0).
The thread 'Flush Thread' (0x8d4) has exited with code 0 (0x0).
The thread '1 : Void Fctn1()' (0x54c) has exited with code 0 (0x0).
Foo invoked from Fctn1
1B


The problem is in function Fctn1() of Form1. It should output a “1A” followed by a “1B” in the console. Instead the Invoke call in Fctn1() appears to be voiding the Join(500) Call in FlushThreadStart() of CommandQueue.cs. I don’t care if the invoked code executes immediately, but why is the rest of the function waiting and how is it getting past the Join? Using a ManualResetEvent causes a deadlock. Any help would be appreciated.
GeneralRe: Threading Problem Pin
S. Senthil Kumar22-Apr-05 22:25
S. Senthil Kumar22-Apr-05 22:25 
GeneralRe: Threading Problem Pin
ACorbs23-Apr-05 17:06
ACorbs23-Apr-05 17:06 
Generalcalculate grade point average for 2 students Pin
keithbg22-Apr-05 16:21
keithbg22-Apr-05 16:21 
GeneralRe: calculate grade point average for 2 students Pin
Dave Kreskowiak22-Apr-05 17:23
mveDave Kreskowiak22-Apr-05 17:23 
GeneralRe: calculate grade point average for 2 students Pin
Christian Graus22-Apr-05 17:49
protectorChristian Graus22-Apr-05 17:49 
GeneralRe: calculate grade point average for 2 students Pin
leppie22-Apr-05 20:58
leppie22-Apr-05 20:58 
GeneralRe: calculate grade point average for 2 students Pin
S. Senthil Kumar22-Apr-05 22:31
S. Senthil Kumar22-Apr-05 22:31 
GeneralRe: calculate grade point average for 2 students Pin
Christian in a nice hotel in Singapore24-Apr-05 0:13
sussChristian in a nice hotel in Singapore24-Apr-05 0:13 
Generalbyte[] to string and back again... Pin
Ian Bowler22-Apr-05 10:49
Ian Bowler22-Apr-05 10:49 
GeneralRe: byte[] to string and back again... Pin
CiNN22-Apr-05 20:32
CiNN22-Apr-05 20:32 
GeneralRe: byte[] to string and back again... Pin
leppie22-Apr-05 21:03
leppie22-Apr-05 21:03 
GeneralgetByte Pin
Anonymous22-Apr-05 10:10
Anonymous22-Apr-05 10:10 
GeneralRe: getByte Pin
Le centriste25-Apr-05 4:37
Le centriste25-Apr-05 4:37 
GeneralSaving image Pin
wetdog50022-Apr-05 9:23
wetdog50022-Apr-05 9:23 
GeneralRe: Saving image Pin
Polis Pilavas22-Apr-05 9:46
Polis Pilavas22-Apr-05 9:46 
GeneralRe: Saving image Pin
wetdog50022-Apr-05 9:54
wetdog50022-Apr-05 9:54 
GeneralRe: Saving image Pin
Polis Pilavas22-Apr-05 9:58
Polis Pilavas22-Apr-05 9:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.