|
Let us know if it works out for you!
Good luck
All the best,
Martin
|
|
|
|
|
Now I am facing the Thread problem since I create a worker thread in the splashscreen that does all the initializing.
I guess it's just a thing I have to live with.
I will keep investigating this and let you know any progress updates!
|
|
|
|
|
Hello,
Maybe you should think about the concept of your splash again.
In my understanding the mainthread should do the initializing (also the mainform) and give the splash the informationions for the user.
If you are showing progressbars and other GUI stuff you would have to use Application.DoEvents().
All the best,
Martin
|
|
|
|
|
Good idea.
Currently, I have managed to fix the problem by invoking a InitializeMainForm method in the thread so it is handled in the main thread again.
Then, I wait until I fire the even mainFormInitialized. This seem to work, but I will definitely try your way too!
Best regards,
|
|
|
|
|
I have now moved everything to the main thread, and all problems are fixed.
Thanks for helping me out on this one!
Best regards,
|
|
|
|
|
Glad I could help!
Geert van Horrik wrote: Thanks for helping me out on this one!
All the best,
Martin
|
|
|
|
|
Hi Geert,
Geert van Horrik wrote: But the combobox is already being filled during the splashscreen
is that what you intend to happen, or do you have actual prove of it ?
BTW: any chance your LoadData() is executed more than once, i.e. the initialization is
maybe OK, but possibly you load the data again by mistake ??
Maybe we need to see more code to actually help you...
Regards
|
|
|
|
|
I am very sure since I add a breakpoint at the ListData of the ComboBox control. It is called during the splashscreen.
When I show the form finally with:
<br />
Application.Run(MainForm.GetInstance());<br />
The breakpoint never gets called again, so I am VERY sure the combobox is already listed. The problem is probably the first time drawing the combobox...
|
|
|
|
|
OK, but drawing a ComboBox is cheap. It is like a TextBox plus a Button (for the arrow);
it is not even interested in its own data unless you click the arrow to drop it down.
So I suspect other things, see my earlier messages (lower in the thread though).
|
|
|
|
|
Hi Geert,
all Controls have SuspendLayout, some also have BeginUpdate.
I dont know what the difference is, probably nothing.
some ideas/suggestions:
- I dont know anything about DB access, but most often I see SQL statements that fill
a DataTable/DataSet, then use that data. Wouldnt that be faster than looping a reader ?
- try your stopwatch on the database stuff independent of the control; if it takes say
5 seconds, then that's what it is, whatever you optimize in the control itself.
- having the splash in the main thread and the initialization in a background thread,
although intuitive, may be the wrong way: I suspect the foreground window and thread
to get priority over the background threads. There is a very complicated scheme of
mapping the 5+1 user defined thread priorities (Normal, aboveNormal, etc, onto the
32 integer levels XP is actually dealing with, and it depends on currentProcess
and window state). Your background worker may sit behind or next to some other
thread in same or other process, your main thread would not (unless the other
thread is "aboveNormal").
Please dont interpret this as a suggestion to start using "aboveNormal" yourself.
The system behavior soon gets very ugly if you do.
Hope this helps.
PS: I typically include logging in all my apps, and each log line starts automatically
with the current time (seconds and milliseconds), so I can more easily see what
happens when, and what takes (too) long.
-- modified at 9:14 Thursday 19th July, 2007
|
|
|
|
|
Thanks for your message and taking the time to help me (same for Martin!).
First about the reader:
When you load everything into a dataset, it must load everything into memory. What I know is that the datareader is the fastest component since it is forward-only and read-only. The dataset is a complete copy of the part of the database which you can edit and update.
Now back to the real problem:
I have a combobox control which loads the db data as soon as I construct the form. So, before I even call the Show form, the combobox already has all the values listed. This process doesn't take very long (about 2 seconds) to list the data from the db and store it in the combobox items property.
However, as soon as I show the form, it takes long (and the items property doesn't get changed anymore at that moment).
That's why I am confused.
|
|
|
|
|
Hi Geert,
this sounds like a different cause all together.
How complex is your form, how many controls are there, anything trying to
setup a connection to a DB or another machine, anything special in there ?
if all is normal, reasonnable and simple:
- how is your CPU load during the wait period ? 100% ? 50 % ? less ? (do you have
a dual core, or a hyperthreading CPU ?
- any Thread.Sleep() included ?
- any cross-thread sins ?
- is it also slow without Visual ? double click the exe, if that is fast, its
because Visual needs some 5 seconds to process the first exception you get
(at least it used to be, dont know the current status on that)
- anything involving several threads with joins and/or possible resource allocation
problems (almost deadlocks) ?
if none of the above help, I see only two routes to go, take your pick:
- add logging with timestamp to a lot of things, and study that log file
- remove a lot of things and watch when it suddenly goes lots faster.
(obviously I prefer the logging methodology).
|
|
|
|
|
Hi Geert,
you got us confused now; at one time you said showing the ComboBox was slow
(I assumed then it was not dropped down, so basically showing an empty TextBox+Arrow,
and clicking it resulted in a very slow dropping down); but now you say
showing the form itself is slow.
depending on which it is, seems to me the splash screen might not be involved at all.
PS: I should have posted this message first, before the one right above it !
|
|
|
|
|
I have a procject in which i am using a custom webclient.
I have following event _WebClient.DocumentComplete which i can register and it works.
Now if I want to unregister the first event handler and assign a new event handler I gives me error because I can't use
_WebClient.DocumentComplete = null;
Can some 1 tell me how to unregister the event
o O º(`'·.,(`'·., ☆,.·''),.·'')º O o°
»·'"`»* *☆ t4ure4n ☆* *«·'"`«
°o O º(,.·''(,.·'' ☆`'·.,)`'·.,)º O o°
|
|
|
|
|
When you add an event handler you use +=
to remove one you use -=
_WebClient.DocumentComplete -= new EventHandler(yourEventHandlerNameHere);
Hope that helps.
Ben
|
|
|
|
|
Hi,
you can undo
someEvent+=new SomeEventHandler(myHandler);
with the following magical line:
someEvent-=new SomeEventHandler(myHandler);
The magic is you create a new object to remove an old (but very similar) object !
|
|
|
|
|
Luc Pattyn wrote: The magic is you create a new object to remove an old (but very similar) object !
I'd always thought you needed to save the old one to unregister it. Learn something new everyday.
How does this work if buggy code results in the same handler being registered twice?
--
You have to explain to them [VB coders] what you mean by "typed". their first response is likely to be something like, "Of course my code is typed. Do you think i magically project it onto the screen with the power of my mind?" --- John Simmons / outlaw programmer
|
|
|
|
|
Dont know, havent seen it spec'd, so I can only suggest you try it.
I can confirm if you register twice, you execute twice (that is a common bug, that
harms performance and is not always apparent).
|
|
|
|
|
dan neely wrote: How does this work if buggy code results in the same handler being registered twice?
Its ugly. You basically get the same handler invoked twice on that event.. I've had to track down so many of these 'event leaks'..
|
|
|
|
|
Hi Dan,
I ran a little test:
private int clicks=0;
private int handlers=0;
Button btn=new Button();
public override void Run(int arg) {
doClick();
addHandler();
doClick();
addHandler();
doClick();
removeHandler();
doClick();
removeHandler();
doClick();
removeHandler();
doClick();
}
void doClick() {
log("CLICK");
btn.PerformClick();
}
void addHandler() {
handlers++;
log("ADD HANDLER "+handlers);
btn.Click+=new EventHandler(btn_Click);
}
void removeHandler() {
log("REMOVE HANDLER "+handlers);
handlers--;
try {btn.Click-=new EventHandler(btn_Click);
} catch { log("failed to remove handler"); }
}
void btn_Click(object sender, EventArgs e) {
clicks++;
log(" got click "+clicks);
}
and it resulted in the following log:
15.109 CLICK
15.125 ADD HANDLER 1
15.140 CLICK
15.156 got click 1
15.203 ADD HANDLER 2
15.218 CLICK
15.296 got click 2
15.312 got click 3
15.328 REMOVE HANDLER 2
15.343 CLICK
15.343 got click 4
15.437 REMOVE HANDLER 1
15.468 CLICK
15.484 REMOVE HANDLER 0
15.593 CLICK
So each -= effectively removes exactly one matching delegate if it finds one,
and does not throw otherwise.
|
|
|
|
|
Hi Dan,
FYI: I just finised turning this subject into a short article. You may want to skim it.
Regards
|
|
|
|
|
Hello Luc,
Luc Pattyn wrote: The magic is you create a new object to remove an old (but very similar) object !
I remember that Scott Dorman once pointed out that it is even possible without creating an new object (I think only in .Net>1.1)
Here is the thread![^]
P.S.: This was my Nr.:1000 post.
All the best,
Martin
|
|
|
|
|
Hi Martin,
I did remember that thread; I havent tried it yet, I still tend to write code that
runs also on 1.1
Martin# wrote: This was my Nr.:1000 post
Aha, that explains a few things. Now take that holiday !
|
|
|
|
|
Luc Pattyn wrote: Aha, that explains a few things. Now take that holiday !
All the best,
Martin
|
|
|
|
|
Have you tried using
_WebClient.DocumentComplete -= <your assigned="" event="" handler="" to="" be="" removed="">;
Is that what you are talking about?
|
|
|
|