|
UI controls should only be accessed from the thread they were created on cause otherwise your application may show some strange behaviour e.g. freezes. Obviously you were lucky and never encountered such problems, but it doesn't mean they will never occur. To inform developers about this possible problem the CrossThreadOperationException is thrown in Framework 2.0.
Some information and ways to get around are presented in this good CP article: What's up with BeginInvoke?[^]
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
I dont have one control to deal on... the number is about 50. so do i've to call begininvoke() for every control im using. isnt there a possible way out like in VS2003.
Bye
|
|
|
|
|
Mr.Sam wrote: so do i've to call begininvoke() for every control im using.
As said you should always use Invoke or BeginInvoke when accessing an UI control from a thread other than the one it was created on. In case you access many controls from your worker thread you could maybe encapsulate all manipulations of the UI in one method and invoke it whenever you want to update the user interface.
Mr.Sam wrote: isnt there a possible way out like in VS2003.
Take a look at Christian's answer.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
hint: it won't work with the Thread , but if ever you should use the Timer class look into the SynchronizingObject property.
V.
I found a living worth working for, but haven't found work worth living for.
|
|
|
|
|
You can turn that exception off, but it's better to write code that doesn't do this, the error is there for a reason.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Ok, looks like no one will give you the "dirty" answer.
Set Control.CheckForIllegalCrossThreadCalls to false when you start up your program and no changes will be necessary. You should be aware this is not proper coding, but for projects that ran ok under VS2003 it's always worked for me. Just be sure to avoid it for anything new you make.
In my opinion Ms could have avoided this issue easily, a mechanism to fix it can be quite easily made, I find doing it over and over again is extremely annoying...
Standards are great! Everybody should have one!
|
|
|
|
|
thanx but where shud i write this line in my code
Bye
|
|
|
|
|
Well, you shouldn't really. If you're gonna use it, put it before your System.Windows.Forms.Application.Run() .
Standards are great! Everybody should have one!
|
|
|
|
|
Thanx a lot man you really solved the problem
Bye
|
|
|
|
|
Nope, didn't solve anything, just ignored it...
Seriously, you should check your program for bugs, there's no guarantee nothing "bad" will happen. Good luck.
Standards are great! Everybody should have one!
|
|
|
|
|
Hi,
if you are lucky you can still do everything on the UI thread by using a
System.Windows.Forms.Timer; your example sure could benefit from it, since
it basically sits sleeping all the time.
if your new thread is there because some real work needs to be done, you could
have that thread set an int progress value, and have a System.Windows.Forms.Timer
with an event handler that updates your progress bar (yes, this is a polling situation,
but hey, it may well be cheaper than the Invoke stuff anayway).
but when your worker thread needs to really interact with one or many controls,
then the InvokeRequired/Invoke/BeginInvoke stuff is necessary.
It then becomes a design decision on how to partition the work; I prefer to use
lightweight methods that do multiple control access at once on the UI thread, so I call
them (with Invoke) when I need them, rather than doing the Invoke stuff for every
individual control access. It goes together with structuring your code anyway...
Luc Pattyn
|
|
|
|
|
Can you plz give me a sample code for manipulating multiple controls using invoke so the real application is responsive and the thread is working on controls.
Thx
Bye
|
|
|
|
|
Hi,
assume a text editor with most operations running on main (= UI) thread, but with search capabilities running on a background thread. When search thread has found what it was
looking for, it calls UpdateSelection() methode to update several things in the user
interface.
Since UpdateSelection is not called from UI thread and needs to access some
controls, we make it such that it calls itself again, this time on UI thread:
public delegate void UpdateSelectionDelegate(int start, int length);
private TextBox textBox;
private MenuItem menuCopy;
private MenuItem menuCut;
public void UpdateSelection(int start, int length) {
if (InvokeRequired) {
Invoke(new UpdateSelectionDelegate(UpdateSelection),
new object[]{start, length});
} else {
textBox.Select(start, length);
menuCopy.Enabled=length!=0;
menuCut.Enabled=length!=0;
}
}
In the example three controls get updated by implementing and executing only one Invoke.
Luc Pattyn
|
|
|
|
|
Cheers for you but can u plz paste the whole code here or refer to the article.
thanks in advance
Bye
|
|
|
|
|
Sorry, I dont have an entire app nor an article about this.
I came up with this code snippet upon your request.
It illustrates the point that you may not have to do the Invoke stuff
for every single control: if you separate the "business logic" or the "model"
of what you are doing, from the user interface, then the number of
times you have to cross the thread boundaries can be limited.
Cheers
Luc Pattyn
|
|
|
|
|
Hi All,
I'm slowing finding my way around C#.
I have written an application that takes a directory, take each file in that directory and also each file in each subdirectory, and then trys to find any files with the same name
(Trying to clear up all my duplicate photos )
SO I have written the code, and checked it and checked it again, it does not get caught in an infinite loop.
But when I F6 the app it comes up with a ContextSwitchDeadlock MDA issue.
So I set the project Properties to "Fully Trusted" and now the app just goes <blank screen="">
I've added a progress bar that slowly grows - This works
I also added a new text box and in the loop set the Text to the fileInfo.Name it was checking. But this does not update on the screen.
Anyone have any ideas how I can Fix the:
1. Context switch/stop the screen blanking out.
2. Fix the Text box updating as it loops through.
As always, thanks for looking and expecially thanks if you reply!
Tony
|
|
|
|
|
The TextBox isn't updated cause the loop you're talking about probably runs on the main UI thread and therefor no other messages (e.g. change text of textbox) are processed until it is done. They are queued in the message pump and get executed after the event handler finishes. Take a look at the Control.Refresh method that forces a visual control to redraw itself immediately.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
Hi Stefen,
Thanks for that. I swear I was looking for a Refresh method, but couldn't find it!. LOL. It worked anyway. Thanks!
Tony
|
|
|
|
|
Gonna bump this as I'm still having the problem!
Tony
|
|
|
|
|
Hi,
Could you please help me to add status bar buttons to the ApplicationMenu in DevExpress. Example button: Word 2007 exit button in Application Menu.
Thanks,
John
|
|
|
|
|
Your best bet is to review the help/samples that came with the product. Then, if that doesn't work, have a look at the support forums on the DevExpress website.
the last thing I want to see is some pasty-faced geek with skin so pale that it's almost translucent trying to bump parts with a partner - John Simmons / outlaw programmer
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
|
|
I need to know that return parameters of SetSystemTime function (that has been located coredll.dll of windows ce 5.0 device) usually returns 1 return type uint. but sometimes i cannot set device time. Is there any idea ?
thanks to all
|
|
|
|
|