472,800 Members | 1,289 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,800 software developers and data experts.

Periodic problem in InitializeComponent of modal form with a forms.timer

Hi,

I have a periodic problem which I am having a real time trying to sort.

Background:
An MDI VB app with a DB on SQL 2000.
I have wrapped all the DB access into an object which spawns a thread to
access the database and then displays a modal dialog which allows the user
to cancel the task, if it is taking longer than they want, and shows them a
display of how long the query has been running so far.

I have been very careful (I think!) to make sure that the UI is only ever
updated from the main UI thread. I pass status info from the SQL therad to
the UI thread through a System.Threading.AutoResetEvent.
A system.windows.forms.timer runs in the Modal form to update a textbox with
the amount of time it has been there and to check the 'SQL finished' event
above.

Everything work fine 99.9% of the time BUT, very occasionally, I get an odd
situation in InitializeComponent in the modal form.
As far as I can ascertain (sorry, that should be, totally guess!), when the
timer is enabled, it does not 'see' the containing forms message loop and so
it instantiates one itself (?). This new message loop 'sees' messages in the
MDI's queue including the pending message currently being processed which
caused this whole event to occur (stay with me here!)

I think that this makes much more sense in the context of a real stack
trace:

Stack Trace: at System.Data.SqlClient.SqlCommand.ValidateCommand(S tring
method, Boolean executing)
at System.Data.SqlClient.SqlCommand.ExecuteReader(Com mandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
at Ideal.clsDBThread.SQLFetchThread()
Current Stack: at System.Environment.GetStackTrace(Exception e)
at System.Environment.GetStackTrace(Exception e)
at System.Environment.get_StackTrace()
at Ideal.basUtility.LogError(Exception e, String strUserMsg)
at Ideal.clsDatabase.SQLFetch(String strCommand)
at Ideal.clsDatabase.TryEditLock(Int32 iDealID)
5 at Ideal.frmDeal.cmdEdit_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventAr gs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage (Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(M essage& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchM essageW(MSG& msg)
at
System.Windows.Forms.ComponentManager.System.Windo ws.Forms.UnsafeNativeMetho
ds+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason,
Int32 pvLoopData)
at System.Windows.Forms.ThreadContext.RunMessageLoopI nner(Int32 reason,
ApplicationContext context)
4 at System.Windows.Forms.ThreadContext.RunMessageLoop( Int32 reason,
ApplicationContext context)
3 at System.Windows.Forms.Timer.set_Enabled(Boolean value)
at System.Windows.Forms.Timer.set_Interval(Int32 value)
2 at Ideal.frmDBExec.InitializeComponent()
at Ideal.frmDBExec..ctor()
at Ideal.clsDatabase.SQLFetch(String strCommand)
at Ideal.clsDatabase.TryEditLock(Int32 iDealID)
1 at Ideal.frmDeal.cmdEdit_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventAr gs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage (Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(M essage& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchM essageW(MSG& msg)
at
System.Windows.Forms.ComponentManager.System.Windo ws.Forms.UnsafeNativeMetho
ds+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason,
Int32 pvLoopData)
at System.Windows.Forms.ThreadContext.RunMessageLoopI nner(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.ThreadContext.RunMessageLoop( Int32 reason,
ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Ideal.basMain.Main()

From the bottom.
Normal appication stack (I think) with a mouse click being processed
At point (1) the routine which handles the button click is called
This calls some SQL which causes the spawned thread/Modal dialog combination
and the modal dialog (Initialisation call can be seen at point 2)
Within this initialisation the timer interval gets set which in turn enables
the timer (point 3). All normal so far
Then:
At point (4), within the timer enable, there is a call to RunMessageLoop
which (I think) hooks onto the MDI's context and picks up the same mouse
click that we are currently processing and recalls the button click routine!
(point 5)

Any help or pointers to help would be VERY VERY apprieciated

Thanks in advance

Stephen
Nov 21 '05 #1
8 2642
Stephen,

In my mind do you need with a problem as yours all the source before your
eyes.

However the first answer on your question is simple. For multithreaded
applications should the forms timer not be used.

There is the threading timer (for me a terrible thing comparing to that easy
forms timer because it is difficult to stop). However it is made specialy
for threading, therefore I would in your place first look for that.

http://msdn.microsoft.com/library/de...ClassTopic.asp

I hope this helps?

Cor
Nov 21 '05 #2
Hi Cor,

Thanks very much for you suggestion.

Unfortunately, I think that using a system.Threading.Timer might cause more
problems rather than solve them? In the MSDN docs they say (About the
TimerCallback) 'The method does not execute in the thread that created the
timer; it executes in a thread pool thread supplied by the system'
The reason for the timer is to update the UI to show how long the task has
been running and so needs to run in the UI's own thread.

Also, although the windows.forms.timer is not thread safe, it is never
accessed from any other thread than the UI one (I hope) and so I don't think
that this will be an issue (as far as I understand the way that the timer is
working?)

I am sure you are right that it is a threading issue, because of the
periodic nature, but I can't for the life of me see where the 'unsafe'
access is going on.

Hmmm.

One other problem I have is that this happens so infrequently that I havn't
been able to recreate the problem myself in a debug environment. All I have
to work from are logs that I have got all the clients to create.

Stephen

"Cor Ligthert" <no************@planet.nl> wrote in message
news:OW**************@TK2MSFTNGP14.phx.gbl...
Stephen,

In my mind do you need with a problem as yours all the source before your
eyes.

However the first answer on your question is simple. For multithreaded
applications should the forms timer not be used.

There is the threading timer (for me a terrible thing comparing to that easy forms timer because it is difficult to stop). However it is made specialy
for threading, therefore I would in your place first look for that.

http://msdn.microsoft.com/library/de...ClassTopic.asp
I hope this helps?

Cor

Nov 21 '05 #3
Stephen,

You mean that what you are doing is

Starting a modal form with a timer as a clock in it and a button
Start in that modal form a thread to read something
Abort that thread when the user pushes the button (when it is not ready)

Cor
Nov 21 '05 #4
Hi Cor,

Yes (but with the following very slight 'frills')

In the main app, start a thread to run the SQL command
Do a 'WaitOne' on a 'SQL thread finished' event with a timeout of three
seconds
If the event did not fire within the three seconds, display a modal dialog
with a 'clock' and a cancel button (I wait for up to three seconds before
doing this so that the, majority, of requests which take less than three
seconds do not have the overhead of creating the dialog and if any user
wants to cancel the SQL task within three seconds they should be shot for
being so impatient!)

The timer tick event first checks for the SQL thread having finished by
doing a very short 'WaitOne' on the event above and then either closes the
dialog with a me.Close if it has or updates a 'clock' label.

If the Cancel button is clicked, it cancels the SqlCommand and then does a
Thread.Join to wait for the DB thread finishing before doing a me.Close.

The main app which created modal dialog does a .Dispose on the dialog form
object when it returns to make sure that the timer is cleaned up.

Thanks again.

Stephen

"Cor Ligthert" <no************@planet.nl> wrote in message
news:OX**************@TK2MSFTNGP15.phx.gbl...
Stephen,

You mean that what you are doing is

Starting a modal form with a timer as a clock in it and a button
Start in that modal form a thread to read something
Abort that thread when the user pushes the button (when it is not ready)

Cor

Nov 21 '05 #5
Stephen

And when you do it as I wrote, what does that mean. The reference too a
dataset is the most simple thing there can be (assuming you are using a
dataset).

Cor
Nov 21 '05 #6
Hi Cor,

I'm really sorry. I am not quite sure what you mean.
Do you mean your suggestion to use the Threading.Timer?

"Cor Ligthert" <no************@planet.nl> wrote in message
news:ev****************@TK2MSFTNGP15.phx.gbl...
Stephen

And when you do it as I wrote, what does that mean. The reference too a
dataset is the most simple thing there can be (assuming you are using a
dataset).

Cor

Nov 21 '05 #7
Stephen,

I mean to start all dataretrival actions from your model form (in that
thread)

Not that I ever tried it, however when I saw you problem I thought why not.

What you want is to get a dataset (I still assume) and in the meantime the
user may (after a shortwhile) only do one thing and that is stop it, what
can be done in that modal form.

Cor
Nov 21 '05 #8
Cor,

Right. (Sorry) I see totally what you mean.

Actually, this is how I had things set up for a very short while when I was
developing it.
The only thing I have against this is that it means the modal form will pop
up for every SQL access which means you can get quite a large number of
popup/disappearing dialogs. Which is A) fairly ugly and B) slows the UI down
a fair amount.

Anoyingly, because I, so far, havn't found a way of forcing the error to
occur, I havn't got an easy way of testing if this does alleviate the
problem.

I think that I will spend a bit of time writing a test prog to fire requests
to the DB one after another and see if I can get the error to occur myself
and then try you suggestion to see if it gets rid of it.

If you have any other thoughts in the mean time. Please give me a shout!

Thanks

Stephen

"Cor Ligthert" <no************@planet.nl> wrote in message
news:O3****************@TK2MSFTNGP12.phx.gbl...
Stephen,

I mean to start all dataretrival actions from your model form (in that
thread)

Not that I ever tried it, however when I saw you problem I thought why not.
What you want is to get a dataset (I still assume) and in the meantime the
user may (after a shortwhile) only do one thing and that is stop it, what
can be done in that modal form.

Cor

Nov 21 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Fulcrum | last post by:
My program has 4 tabs with a few usercontrols that each have a lot of controls on them. Added to that a few oleDb database connections etc. Because of this the program spends a lot of time during...
2
by: cassidyc | last post by:
Hi, I was wondering if anyone has come accross this issue? And if they have any solutions I have that can create new copies of itself Form1 as = new form1(); af.show(); This form can also...
2
by: jamie | last post by:
I have a class that based on a timer will pop up a dialog based on a lasped amount of time. The problem is that in the timer elapsed event I create and use ShowDialog to show the timeout form:...
2
by: Mike | last post by:
Hi, I'm having a problem with modal forms on windows. I've written a very short test program, with a main window and a form called from the main window. The form is set to modal with...
8
by: =?Utf-8?B?RGF2ZQ==?= | last post by:
Is this possible? I have 3 forms frmGrandparent, frmParent & frmChild. Can frmGrandparent do a frmParent.ShowDialog() and then (while frmParent is open) do a frmChild.ShowDialog(). At the end of...
2
by: diogenes | last post by:
I have created many shortcut/popup (aka context, or right-click) menus for my application - instead of toolbars or standard drop-down menus. Within my custom menu, I am using...
4
by: =?Utf-8?B?Z2luYWNyZXNzZQ==?= | last post by:
I am trying to close/dispose multiple instances of a form but because they are modal and hidden, they do not show up in My.Application.OpenForms. They must be modal, so making them modeless is not...
1
by: Mohit | last post by:
Hi all, I am working on a windows based client server application with multiple forms. All forms are having custom title bars with no default bars. There is one main form. Some forms are opened up...
8
by: poko | last post by:
I want a textbox on the form to show the current time. The code I have written follows. But it does not work and I don't know why :( Can someone please point out the error. using System; using...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.