|
Luc Pattyn wrote: I considered that too, but I would probably never use it. Most apps have several ways to get something done (MainMenu.MenuItem, ContextMenu.MenuItem, Button, KeyDown), so there isn't just a single Control to disable, I often have a Command object that sits in between several Controls and a single Action, however that would make my WaitCursor too specialized IMO.
True, and I rarely take the time to encapsulate it in an action-class that's responsible for synchronizing it's state; most actions in a WinApp can be initiated from multiple points in the application, each needing to be updated to reflect it's status.
Luc Pattyn wrote: Never used it. As it is bound to be a short operation, I probably would not care much. Longer operations, I'd do in a BGW, and I make sure the GUI updating is periodic rather than continuous.
Sounds like a better approach than disabling drawing for more than a second.
Tx
Bastard Programmer from Hell
|
|
|
|
|
Hi Luc,
Yes, I fully understand what you are doing in the class: I created it myself, out of curiousity, before you posted your example here, and tested it, with the significant exception that I changed a Control's (Button, whatever) Cursor to 'WaitCursor, I didn't change the Cursor on the entire Form.
Do you have any evidence whatsoever that changing the visual appearance of a Cursor on a Control or a Form is a cause of a memory leak, or consumes resources in a way that is not garbage collected ? And, that the solution you present here in any way prevents a memory leak ?
I repeat that there is no valid reason for use of such a technique for so simple a task as changing the visual appearance of a Cursor, and, for those not-common, and well-documented cases, where .NET tells us we should bracket certain objects in a 'Using {} block, the reasons are crystal clear.
This kind of over-engineering for simple tasks is what I refer to as "gratuitious elegance." And, if I were a beginner in .NET, I would find this truly confusing.
You wrote: "So there may be hundreds of using(new LP_WaitCursor(this)) statements in a single app, each one replacing a pair of Cursor=... statements."
My mind boggles trying to envision what type of application really uses "hundreds" of such classes, winking and blinking out of existence, each storing a reference to a Form.
If (please, don't let it happen) I ever saw an application with "hundreds" of uses of such a class, with all kinds of controls putting a 'WaitCursor' on an entire Form, I would promptly conclude that: there's an application where the fundamental design involving threading is ... to put it mildly ... 'off the planet.'
I can, indeed, imagine a scenario in which some tasks are so critical, their completion essential to so many pending-task-dependencies, that an entire application (or its UI) should "freeze up," or at least present some modal, ... even can't-be-cancelled ? ... dialog or progress bar, or whatever (nuclear power plant control ?), by the way.
disputatur in spiritu fratribus, Bill
"Is it a fact - or have I dreamt it - that, by means of electricity, the world of matter has become a great nerve, vibrating thousands of miles in a breathless point of time? Rather, the round globe is a vast head, a brain, instinct with intelligence!" - Nathanial Hawthorne, House of the Seven Gables
|
|
|
|
|
Hi Bill,
1.
memory leak prevention and memory consumption aren't a factor here. All the IDisposable interface and the using pattern achieve is Dispose() is getting called, what you do inside Dispose() is up to you, it doesn't have to relate to memory or resources, see it as "automatic post-processing".
2.
I didn't say it was all happening on a single Form. A database (or any networked) application could easily have say 10 Forms, each Form having five buttons, and a memu bar with 5 main menu's, each holding 5 menu items. That is 250 menu items and 50 buttons all together. And more tables in the database would probably lead to more Forms, more Controls, more WaitCursors.
If I expect any of the click handlers to regularly take more than say 100 msec to execute, I'd use threading, disable the Control and probably show a progress bar and possibly a Cancel button, I would then NOT show a WaitCursor (IMO WaitCursors are for synchronous operations only).
If OTOH I expect those actions to normally take less than 100 msec, then I'd organize them as a synchronous operation, running on the main thread; I would then typically not disable the Control, and show a WaitCursor instead. Of course I'd organize the WaitCursor at the front of the click handler; I would not hide it somewhere in the data access layer (which would reduce the number of WaitCursor statements but also violate the separation-of-concerns concept.
3.
The frequency of LP_WaitCursor instantiations is pretty low, as they appear only in some GUI handlers, i.e. they require the user to click something. That is expected to be less than once per second. If you really care about the number of objects created, abandoned, and finally collected in an app (which I do care about very much), then I suggest you:
- eliminate all new keywords inside handlers that don't take human action as a trigger, say the Paint , Tick , and DataReceived handlers. Ideally there should be NO new Font(...) or new Pen(...) or new Anything(...) inside those, that is where performance is going down the drain.
- carefully investigate everything you do with strings. Most apps, as soon as they are doing something, create hundreds of strings per second, most of them extremely short lived. Using StringBuilder may reduce those numbers, and it may or may not improve performance, however IMO it is strings that justify the existence of automatic garbage collection, and once you have that in place, I don't mind creating a few more objects I could do without, but choose to have, mostly for structuring my code and improving code readability.
|
|
|
|
|
Hi Luc,
+5 Once again I would like to thank you for the extended response. To be able to hear from someone at your level of technical excellence is a privilege !
The information provided in your last response shifts the entire frame of reference of this discussion to a multi-user, multi-session, (undoubtedly multi-threaded ?) application, probably client-server, with multiple tiers, data-access layers, business rules ... at least one of every fruit that was ever on one of Carmen Miranda's hats
In those circumstances the architecture you describe makes perfect sense, of course.
But, that scenario was not where this discussion started. It started with a simple question about why a visual cursor didn't properly refresh, probably in an asynchronous application without use of explicit threading.
And, I must point out that you were the one who specifically mentioned the use of "hundreds" of instances of your LP_WaitCursor class, which I wondered, at the time I read it, if you were perhaps speaking in 'hyperbole.'
Your excellent advice about 'exorcising' as much use of 'New' as possible, and using StringBuilder were long ago adopted by me as a general principle.
How I (and others ?) would appreciate an article from you discussing in more detail your approach to threading strategy and ui update !
best, Bill
"Is it a fact - or have I dreamt it - that, by means of electricity, the world of matter has become a great nerve, vibrating thousands of miles in a breathless point of time? Rather, the round globe is a vast head, a brain, instinct with intelligence!" - Nathanial Hawthorne, House of the Seven Gables
|
|
|
|
|
Hi Bill,
you're welcome. And I hope all is clear now.
At some point in time I was considering writing an article on threading, however I decided against it when I saw a large number of new CP articles on the subject, there even is a series by Sacha[^] which is bound to be excellent. I must admit I haven't read them, but I doubt there is much I could add.
|
|
|
|
|
As others have already mentioned, the use of using for this purpose and similar ones is a very interesting technique.
However, in this situation, it won't work. The long lasting operation is started (by user pressing a button) sending a message to some hardware device. The application then waits for an answer, sends another message, waits and so on. The operation is finished when receiving a message meaning "All done" or "Error".
Since start and end of the operation reside in separate methods, I'll stick with explicit calls to
someControl.UseWaitCursor = someBooleanValue and try setting the focus to make it happen immediately.
As for the side note: communication runs in another thread, of course.
And user shall not be allowed to do anything in the meantime except for pressing the cancel button (by customer request). Therefore, all controls are disabled except for the cancel button and all its parenting controls up to the main form.
Ciao,
luker
|
|
|
|
|
With the risk of stating the obvious, a simple way to disable all controls while showing a progress bar and cancel button, is using a progress dialog (modally, with ShowDialog), which just holds the progress bar and cancel button.
|
|
|
|
|
I think you've run into a Windows quirk here. I've had this behaviour with other applications, and most of them weren't .NET.
If the user is waiting for a while for the program to load/complete work, then it might be more elegant an idea to give more interface cues than just the wait cursor changing, such as a status text, or progress bar, etc.
|
|
|
|
|
What is the best practice for deploying Crystal reports documents with a WinForms app? I understand how to deploy the modules and runtime executables, my question is about the actual documents themselves. I was thinking of deploying them with the application in a reports folder accessed using System.Reflection, but is there a better way or is this pretty much the best bet?
|
|
|
|
|
I've worked with a few enterprise software packages that use Crystal Reports. The most common way to do it seems to be just like you've described... drop the report files in a Reports folder along with the other application files. From there, using a relative path combined with the execution path would be the most flexible.
I've also seen a software system that allowed you to check-in/check-out reports from the database. Not only was this used to capture metadata about the reports but also to store them in a database instead of the standard file structure. I think it really boils down to whether or not you want the reports to be accessible (easily) or not and if you'll be having user functions within the app to manipulate the reports (e.g. adding new ones).
|
|
|
|
|
I have a c#.net 2008 desktop application that I need to add logic to authenicate who the user is. I am going to use windows authenication to connect to the active directory to verify the right of each person by group. Thus I have the following question for a desktop application;
1. Do you know of a reference of that has a desktop form accessing the active directory? The only one I know about is an asp.net applcation accessing the active directory.
2. In this application, I would like the windows desktop application to pass the authenication(active directory) information to sql server 2008 r2 by either user or by group.
Thus I am wondering if you can point me to some references (links and/or urls) i can use to accomplish these tasks or part of these tasks.
|
|
|
|
|
dcof wrote: 1. Do you know of a reference of that has a desktop form accessing the active
directory? The only one I know about is an asp.net applcation accessing the
active directory.
Virtually no difference in how you do it.
dcof wrote: 2. In this application, I would like the windows desktop application to pass the
authenication(active directory) information to sql server 2008 r2 by either user
or by group.
Use Integrated Security in the connection string and it will do it for you.
|
|
|
|
|
You basically said there is Virtually no difference in how you do it. Basically how you connect a desktop application versus a asp.net to the active directory. However, can you tell me what the difference is?
|
|
|
|
|
The only real difference is where you get the current user info from for your authentication.
In asp, I use this function (everyone stop laughing...I never got around to cleaning it up):
public string Whoami()
{
string str;
int idx;
str = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name;
idx = str.IndexOf("\\");
return str.Substring(idx + 1);
}
But on the desktop, all you need is:
string SAMS = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Then diddle a little with it to get just the login:
string[] SAM = SAMS.Split(Delim, StringSplitOptions.RemoveEmptyEntries);
with SAM[1] being the login without the domain.
After that, you can check AD to see if the user is authorized, or whatever.
|
|
|
|
|
Hi
I have a WPF application which I don't want to rewrite again inside another new Winform app - how can I host the WPF app from inside a Winform? Thinking of digging a hole on Winform, through the hole shows the old WPF app. But the two apps/exe need to align, move and resize together. Wonder how this can be done (comm by socket a possibility).
dev
|
|
|
|
|
|
Hi,
I'm trying to block some websites using the hosts file located on C:\Windows\System32\drivers\etc\
contents are:
127.0.0.1 www.facebook.com
Any idea why Windows7 ignores it??
Many thanks
|
|
|
|
|
I copy/pasted your entry, and it works for me (also on Win7) Ran notepad as an administrator, added the entry, opened IE, and can't find FB.
Did it add a ".txt" extension to your file? It might be that Windows is hiding the file-extension.
Bastard Programmer from Hell
|
|
|
|
|
Any changes should be seen immediately, however, you may have to flush any caches and reload the tables
ipconfig /flushdns
nbtstat -r
from the command prompt.
|
|
|
|
|
i am currently working on onject database which needs a high level mutli page client front end. using the normal windows forms in visual basic look low cost and very baisc is there front end software package or code that l can use to develop a more up market look. I m not the best t programming and foind it near impossible to get a local (paid) assistance to finsh this project so any help would be gratefully appricated
Cheers cool site been watching for a while and it seems good idvice almost all of ther time keep up the good work guys happy to assit were l can
jon
|
|
|
|
|
|
thank you for the assistance will do
cheers
John
|
|
|
|
|
You could use Visual Studio Express Editions to start building some applications.
However, you should have some basic programming knowledge.
|
|
|
|
|
thanks for that i have been using vb but l was looking for A MORE POLISHED look but thanks you for taking the time to respond to question
jon
|
|
|
|
|
I'm not entirely sure what you mean by 'polished', but you could check out MDI forms in Visual Studio, which is the basic Windows way of working with multiple documents.
|
|
|
|
|