Click to See Complete Forum and Search --> : why is my form multi-threading


JoeBuntu
October 25th, 2009, 06:17 PM
I have a button on a form that runs the snippet below.
If you press the button rapidly it appears as though the code is running on a separate thread from the form shown by the debug output:
Start: 0
Finish: 4
Start: 4
Finish: 4
Start: 4
Start: 0
Finish: 4
Start: 4
Finish: 4
Start: 4
Start: 0
Start: 0
Finish: 4
Start: 4
Finish: 4
Finish: 8
Finish: 12
Finish: 16

what the code does is clear a list view, query a database and fill the list view with the results.
with the paramaters I am using I should end up with 4 items in my listview every time, but when I do it rapidly I am ending up with a multiple of 4!!

I thought that any code that handles form events runs on the same thread as the form and therefore the button shouldn't respond to any further click events until the code is completed?

Just to see if it would work I added the lock(lock_obj) block and it doesn't seem to work either.

I could probably get around the whole problem by disabling the button and then enabling it, but I would like to know why/how this is happening and why isn't lock(lock_obj) working?
thanks

private object lock_obj = new object();
private void btnSearch_Click(object sender, EventArgs e)
{
lock (lock_obj)
{
System.Diagnostics.Debug.Print("Start: " + m_PoIdList.Count.ToString());
lviewResults.Items.Clear();
m_PoIdList.Clear();
lblResults.Text = "Results: ";
Application.DoEvents();

if (m_QueryBuilder.AnyParametersSet)
{
foreach (InboundPOReadonly po in InbPosDB.GetPoItemsReadOnly(m_QueryBuilder.GenerateCommand()).Values)
{
string[] props = new string[7]
{po.Id.ToString(), po.PO, po.VendorName, po.ReceivedDate.ToShortDateString(),
po.User, po.Timestamp.ToShortDateString() + " " + po.Timestamp.ToLongTimeString(), po.ItemCount.ToString()};
m_PoIdList.Add(po.Id);
lviewResults.Items.Add(new ListViewItem(props));
}
System.Diagnostics.Debug.Print("Finish: " + m_PoIdList.Count.ToString());
lblResults.Text = "Results: " + m_PoIdList.Count;
}
else
MessageBox.Show("No Parameters have been set");
}
}

JoeBuntu
October 25th, 2009, 06:21 PM
Using 3.5 framework

BigEd781
October 25th, 2009, 06:35 PM
You should study up on how Windows actually works. When you click button messages are being queued up in the windows message pump. So, if you click it n times, n messages are pushed onto the queue. If you don't want this to happen, simply disable the button after it is clicked and re-enable it when your processing has finished.

JoeBuntu
October 25th, 2009, 07:02 PM
I hear what your saying but if my form is only executing on one thread then how could it possibly be doing two things, in this case the same block of code, at the same time?

BigEd781
October 25th, 2009, 07:19 PM
I hear what your saying but if my form is only executing on one thread then how could it possibly be doing two things, in this case the same block of code, at the same time?

No, it's not. Multiple threads are running in the background, regardless of any threads that you have started yourself. The OS and the runtime are doing a lot of work for you behind the scene. If you *really* want to know what is going on, make a couple of UI's using pure Win32 API calls. That's how I learned Win32, and though it is painful, it is a good learning experience.