|
But its making the print slow, right now am using this way.
PrintTextWrite.WriteLine(PSLNO.PadRight(3) + " " + PKCODE.PadRight(14) + " " + PITEMNAME.PadRight(45) + " " + PQTY.PadLeft(40) + " " + PRT.PadRight(11) + " " + PTOT1.PadLeft(20));
but when size of PITEMNAME increases PQTY,PRATE,PTOT1 will go off the paper
|
|
|
|
|
Hi,
I have written an application (.NET 1.1, Windows.Forms) successfully running on not-Vista. But a customer reported, that under Vista the application is killed by Windows somewhere during his session after clicking a button, which starts a time-consuming calculation. (Other customers have this application running successfully under Vista)
Vista pops up a form
"myApp has stopped working. A problem has caused the program to stop working correctly. Windows will close the program and notify you if a solution is available."
Hm, Windows is able to do that...? Well...
Nevertheless I want to get active to find the error.
Perhaps I should mention that the progress-bar form for that calculation, which runs in a separate thread, is opened successfully immediately before the crash.
Following exception was noted by my application:
System.ObjectDisposedException: Cannot access a disposed object.<br />
Object name: 'myApp'.<br />
at System.Windows.Forms.Control.CreateHandle()<br />
at System.Windows.Forms.Form.CreateHandle()<br />
at System.Windows.Forms.Control.get_Handle()<br />
at System.Windows.Forms.Form.FillInCreateParamsStartPosition(CreateParams cp)<br />
at System.Windows.Forms.Form.get_CreateParams()<br />
at System.Windows.Forms.Control.CreateHandle()<br />
at System.Windows.Forms.Form.CreateHandle()<br />
at System.Windows.Forms.Control.get_Handle()<br />
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)<br />
at System.Windows.Forms.Form.SetVisibleCore(Boolean value)<br />
at System.Windows.Forms.Control.Show()<br />
at ImageIron.this_Load(Object obj, EventArgs ea)<br />
at System.Windows.Forms.Form.OnLoad(EventArgs e)<br />
at System.Windows.Forms.Form.OnCreateControl()<br />
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)<br />
at System.Windows.Forms.Control.CreateControl()<br />
at System.Windows.Forms.Control.WmShowWindow(Message& m)<br />
at System.Windows.Forms.Control.WndProc(Message& m)<br />
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)<br />
at System.Windows.Forms.ContainerControl.WndProc(Message& m)<br />
at System.Windows.Forms.Form.WmShowWindow(Message& m)<br />
at System.Windows.Forms.Form.WndProc(Message& m)<br />
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)<br />
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)<br />
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Does anybody know that problem?
Thanks in advance,
Alex
|
|
|
|
|
AlexZieg71 wrote: Does anybody know that problem?
Yes, you're trying to access a disposed class, an the same exception can be generated by using this code:
Form newForm = new Form();
newForm.Dispose();
newForm.Text = "Hello World!"; You'll have to provide some code or a stack trace for us to help you track down the problem.
|
|
|
|
|
Thanks for your reply! But if I knew the failing code I would be happy to post it here...
I think that it must be a Vista-specific behaviour, because the same application has been running on other Windows-versions for many months now. Perhaps the exception was thrown because my application wanted to continue, but Vista disposed the main Form for some (?) reason...
|
|
|
|
|
I ran into a similar problem. On Vista, .NET seems to run it's garbage collection more frequently or something; because I had code which was accessing an object I had released, and it never complained on XP, but always threw an exception in Vista.
|
|
|
|
|
Hm, I will have a look on this, too. Thanks!
|
|
|
|
|
Are you doing any communication across threads? e.g. thread 2 tells thread 1 to update the progress bar - anything like that?
Alternately, you aren't accessing a progress bar (or any other control) on a thread other than the one that created it, are you?
|
|
|
|
|
No. The main thread creates the progress-bar form in a second thread and updates a progress value which is checked by a Timers.Timer in this second thread 4 times a second.
Is there a known Vista-specific behaviour in multi-threading?
|
|
|
|
|
So, the second thread that creates the progress bar form - is that thread STA? Any thread that creates controls or windows needs to be STA apartment state.
Another thing you might want to check is, are these timers still running in the background when the progress bar form is disposed/closed? I'm picturing some timer or the first thread telling the progress bar form to do something, but it turns out the progress bar form is disposed, causing your exception.
I suspect what you're seeing isn't Vista-specific, but rather, is a race condition that happens only under certain circumstances or perhaps with a certain processor architecture (multicore, hyperthread, etc.) that handles threading differently, causing your race condition to occur more often.
|
|
|
|
|
Yes, I think so (?), because the main thread runs as STA.
The timer is stopped and disposed when the form closes (Form.Closing event). Do you think it is a problem, that the form is closed from the main thread or that the main thread manipulates the progress-value in the progress-bar form?
|
|
|
|
|
AlexZieg71 wrote: Yes, I think so (?), because the main thread runs as STA.
The second thread won't automatically be in the correct apartment state. Here's code that sets the right apartment state:
Thread myThread = new Thread(new ThreadStart(someFunctionThatCreatesControlsOrWindows));
myThread.SetApartmentState(ApartmentState.STA);
myThread.Start(); Remember, STA is required only if that thread will be creating windows or controls. If the thread is just doing background work, don't worry about apartment state.
Also remember: when you create a new thread yourself (or use one from the thread pool via the ThreadPool.QueueUserWorkItem method), the thread will be in the MTA state by default.
Regarding your timer stuff, it's almost certain it's a threading issue -- the main form thread is manipulating values (e.g. changing shared state) in the 2nd thread; this is dangerous. Also, closing the progress form from the main form thread is dangerous.
Fortunately, there's a simple solution to both of these problems:
Instead of modifying variables shared between threads, just have the main thread tell the progress form to do it for you. That way, the progress form alone is king, and doesn't have to worry about sharing variables and state with the main thread. To do this, do something like:
ThreadStart functionThatUpdatesSomeProgressFormVariables = new ThreadStart(...);
progressForm.BeginInvoke(functionThatUpdatesSomeProgressFormVariables);
Same with closing the progress form. Instead of closing the progress form from the main thread, just have the main thread tell the progress form to close:
ThreadStart closeTheProgressFormFunction = new ThreadStart(CloseTheProgressForm);
progressForm.BeginInvoke(closeTheProgressFormFunction);
...
void CloseTheProgressForm()
{
progressForm.Close();
}
I'd also add that .NET 2 makes this insanely simple using either the BackgroundWorker component, anonymous methods, and delegate inference. If you're stuck on .NET 1.x, you might try looking up an article on this site that created a BackgroundWorker component like the one in .NET 2, but works on .NET 1.x. It will save you the headache of calling control.Invoke/control.BeginInvoke, you won't have to think about apartment states, and it will let you focus on your code rather than thread synchronization issues.
|
|
|
|
|
|
I concur the most likely problem is a cross-thread violation, which can go unnoticed for
a long time when using .NET 1.x; it will cause your app to hang or behave strangely at
any point in time. It would have been catched by .NET >= 2.0 which throws an InvalidOperation
Exception. This is not Vista-specific, but maybe Vista is more likely to make the bug show
itself.
I would suggest you switch to .NET 2.0 to figure it out (this requires all your code
gets recompiled under Visual Studio 2005, so you can no longer use existing .NET 1.x DLLs).
Either temporarily to locate the problem and fix it, or permanently.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Thanks, see my reply to Judah. Do you see a violation in this procedure?
|
|
|
|
|
Hi,
in practice all Controls should be created by a single STA thread, normally that is
the initial thread. Reason is 1) there is no inherent thread safety in Windows,
and 2) all Controls typically are linked somehow (added to the Controls property
of the main Form, or something similar).
The timer handlers, the SerialPort datareceived handler, and many others run on another
thread and are inappropriate to create Controls , or read or write Control properties,
or call Control methods. There is one exception: the Windows.Forms.Timer, it "ticks"
on the main thread.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
This sounds good, but another question would be why it worked on other Vista installations...
|
|
|
|
|
AlexZieg71 wrote: why it worked on other Vista installations
sorry, this question is irrelevant; a lot of bugs don't show immediately, their negative
impact will only show under certain circumstances, but trust me, as long as your code is
not theoretically sound, they WILL show up in the end.
Under .NET 1.0, .NET 1.1, and all later versions if you turn off the checking:
the cross-thread violations typically hide for a while, then suddenly show up as a slight
GUI malfunction, maybe the main menu remaining blank, or maybe a complete freeze. Activating
another app, then reactiving your app, increases the likelihood the GUI goes wrong.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
OK, I think you are right... That means that I will have to all bigger calculations into worker threads and put the progress bar into the main thread. Glp...
|
|
|
|
|
Alex, if possible, check out the .NET 2 BackgroundWorker component. It does all the thread-marshaling issues for you, allowing you to focus on your background work and UI updates by themselves.
If you're stuck on .NET 1.x, search this site for BackgroundWorker for .NET 1, there are folks who've implemented the component using .NET 1.x.
|
|
|
|
|
Through property window changing form1/mainform text is is very easy. But i want change it at runtime but i can't access form1.text/this.text like property.Pls solve it?
|
|
|
|
|
Why can't you access it as a property? You can assign the Text property on the form to change the form's text. From inside the form class you can do:
this.Text = "New Title";
From outside the form class you can do:
form.Text = "New Title";
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
If i want to calculate time like this time / pages * 100 = time per 100 pages
for example:
00:05:00 / 5 = 00:00:01 * 100 = 00:01:40
Any suggest
tnx
|
|
|
|
|
Wasn't this answered a few weeks ago?
|
|
|
|
|
It was just a week ago this was answered, here[^]. All you have to do is apply a little math.
|
|
|
|
|
I answered this question in the thread that you created a week ago.
If you keep reposting the same questions without following up on the replies that you actually get, people will stop answering your questions all together.
---
single minded; short sighted; long gone;
|
|
|
|
|