473,396 Members | 1,734 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

.InvokeRequired always resulting in true

Wow... unbelieveable that this problem would arise right before giving the
software to our public testers... or maybe it is believable. We tweaked some
seemingly unrelated code somewhere else having nothing to to with this
object, and now the following function is causing a
System.StackOverflowException:

private void ResetAllDataFieldsSafely()
{

if(myWebBrowser.InvokeRequired) //always evaluates to true
{
SafelyResetAllDataFieldsDD d = new
SafelyResetAllDataFieldsDD(ResetAllDataFieldsSafel y);
this.Invoke(d);
}
else
{ // now this should be running on the main GUI thread
ResetAllDataFields();
}
} // end ResetAllDataFieldsSafely ()

myWebBrowser.InvokeRequired always is true now! I will watch it in debug
mode and indeed this is an infinite loop. Why on earth is this happening?
Is there something strange you can do to a web browser object that will
always cause it to evaluate to true? I am calling ResetAllDataFieldsSafely()
from another thread.

It worked before...

Thanks to anyone and everyone who reads this,

Rob K
Aug 1 '06 #1
5 5607
RobKinney1 <Ro********@discussions.microsoft.comwrote:
private void ResetAllDataFieldsSafely()
{

if(myWebBrowser.InvokeRequired) //always evaluates to true
{
SafelyResetAllDataFieldsDD d = new
SafelyResetAllDataFieldsDD(ResetAllDataFieldsSafel y);
this.Invoke(d);
}
else
{ // now this should be running on the main GUI thread
ResetAllDataFields();
}
} // end ResetAllDataFieldsSafely ()

myWebBrowser.InvokeRequired always is true now!
Interesting. I must say, in C# 2.0, I would write the following:

myWebBrowser.Invoke((MethodInvoker) delegate
{
ResetAllDataFields();
});

.... and rely on Invoke dispatching it properly.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #2
Barry! Thanks for replying! I wish I could have known about this sooner.
Excellent. It seemed I looked forever before I finally stumbled accross the
solution I had origninally.

Here is my confession though... I have 3 seperate browsers in my program.
Contained within ResetAllDataFields(), I destroy and then recreate all of
them (along with resetting a lot of different data). I simply latched onto
myWebBrowser because it was contained withing ResetAllDataFields() and it was
originally the one throwing a COM error when I was calling this from a worker
thread.

It seemed that in my function, if I just checked this object beforehand, I
would know if ResetAllDataFields needed to be invoked on the main thread..
But technically since I am grabbing all 3 browsers and destroying/creating
them within this function, I could have used any of them right there.

Is this sloppy? If so, how can I tell within a function like
ResetAllDataFieldsSafely() whether or not it is being run from a worker
thread or the main thread (without using a random control)?

I put in your suggested code where my original function call was and it
yielded the following error when it came accross another browser object when
destroying and recreating it:

"Controls created on one thread cannot be parented to a control on a
different thread."

(better than the infinite recursion!!)... but this leads me to believe that
even the invoker is trying to launch ResetAllDataFields on the worker
thread....

Am I missing something here?

Thank you so much for your help.

Rob K
"Barry Kelly" wrote:
RobKinney1 <Ro********@discussions.microsoft.comwrote:
private void ResetAllDataFieldsSafely()
{

if(myWebBrowser.InvokeRequired) //always evaluates to true
{
SafelyResetAllDataFieldsDD d = new
SafelyResetAllDataFieldsDD(ResetAllDataFieldsSafel y);
this.Invoke(d);
}
else
{ // now this should be running on the main GUI thread
ResetAllDataFields();
}
} // end ResetAllDataFieldsSafely ()

myWebBrowser.InvokeRequired always is true now!

Interesting. I must say, in C# 2.0, I would write the following:

myWebBrowser.Invoke((MethodInvoker) delegate
{
ResetAllDataFields();
});

.... and rely on Invoke dispatching it properly.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #3
RobKinney1 <Ro********@discussions.microsoft.comwrote:
Here is my confession though... I have 3 seperate browsers in my program.
I presume they are in different windows? With the error below, are your
windows created on different threads? Do you mean to do this?
Contained within ResetAllDataFields(), I destroy and then recreate all of
them (along with resetting a lot of different data). I simply latched onto
myWebBrowser because it was contained withing ResetAllDataFields() and it was
originally the one throwing a COM error when I was calling this from a worker
thread.
I presume you know that you need to do all this work on your GUI thread,
since Windows' windows have thread affinity.
It seemed that in my function, if I just checked this object beforehand, I
would know if ResetAllDataFields needed to be invoked on the main thread..
But technically since I am grabbing all 3 browsers and destroying/creating
them within this function, I could have used any of them right there.
You should create them on the GUI thread, not in your worker thread,
IMO.
Is this sloppy? If so, how can I tell within a function like
ResetAllDataFieldsSafely() whether or not it is being run from a worker
thread or the main thread (without using a random control)?
In your situation, I'd make sure that everywhere that needs to
communicate with the UI has a reference to something which implements
ISynchronizeInvoke (every control does) and pass a delegate to its
Invoke() method.

Because of the way anonymous delegates capture variables from the outer
context, it's as simple as a 'using' block - Invoke + anonymous delegate
simply and relatively efficiently switches context to the GUI and you
can code on.
I put in your suggested code where my original function call was and it
yielded the following error when it came accross another browser object when
destroying and recreating it:

"Controls created on one thread cannot be parented to a control on a
different thread."
That's a pretty serious error. You need to create and parent controls
all on the GUI thread. There are ways to get separate top-level windows
to run on separate threads in WinForms, but it isn't recommended if it
can be avoided, for complexity reasons.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #4
Thank you for responding again Barry.

I think I have some work to do. I have gone back to a backup from last
Friday and am reconstructing the recent changes I had made.

You information is very valuable now that I can start from here and build it
up the correct way.

Supposedly that function was supposed to be invoking the reset procedure on
the main GUI thread (called from the worker threads) but somehow... someway
it started to fail (as described above -- probably the case of fat finger on
my part)... I wonder if that is even possible...

Nonetheless, I am back and hard at work. Thank you for your comments. I
will post back when I get it working. :~}

Rob K

"Barry Kelly" wrote:
RobKinney1 <Ro********@discussions.microsoft.comwrote:
Here is my confession though... I have 3 seperate browsers in my program.

I presume they are in different windows? With the error below, are your
windows created on different threads? Do you mean to do this?
Contained within ResetAllDataFields(), I destroy and then recreate all of
them (along with resetting a lot of different data). I simply latched onto
myWebBrowser because it was contained withing ResetAllDataFields() and it was
originally the one throwing a COM error when I was calling this from a worker
thread.

I presume you know that you need to do all this work on your GUI thread,
since Windows' windows have thread affinity.
It seemed that in my function, if I just checked this object beforehand, I
would know if ResetAllDataFields needed to be invoked on the main thread..
But technically since I am grabbing all 3 browsers and destroying/creating
them within this function, I could have used any of them right there.

You should create them on the GUI thread, not in your worker thread,
IMO.
Is this sloppy? If so, how can I tell within a function like
ResetAllDataFieldsSafely() whether or not it is being run from a worker
thread or the main thread (without using a random control)?

In your situation, I'd make sure that everywhere that needs to
communicate with the UI has a reference to something which implements
ISynchronizeInvoke (every control does) and pass a delegate to its
Invoke() method.

Because of the way anonymous delegates capture variables from the outer
context, it's as simple as a 'using' block - Invoke + anonymous delegate
simply and relatively efficiently switches context to the GUI and you
can code on.
I put in your suggested code where my original function call was and it
yielded the following error when it came accross another browser object when
destroying and recreating it:

"Controls created on one thread cannot be parented to a control on a
different thread."

That's a pretty serious error. You need to create and parent controls
all on the GUI thread. There are ways to get separate top-level windows
to run on separate threads in WinForms, but it isn't recommended if it
can be avoided, for complexity reasons.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #5
Thanks Barry. Everything is working great now. I am using your
MethodInvoker example and it has solved more than just this problem.

Hopefully one day I can be of service to you as well.

Excellent!

Rob K
Aug 2 '06 #6

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

Similar topics

9
by: David Sworder | last post by:
Hi, I have a form that displays data (is that vague enough for you?). The data comes in on a thread-pool thread. Since the thread pool thread is not the same as the UI thread, the callback...
2
by: Sgt. Sausage | last post by:
Problem. Work-around. No issues, just looking to see if I'm the only one that's seen this. I just lost 3 hours (shoulda found it sooner) to the InvokeRequired on a form being somewhat...
2
by: BoloBaby | last post by:
Earlier, I had a threading issue where I had to use the InvokeRequired to get my controls to function properly. Does InvokeRequired apply to my custom classes as well? That is, if I have...
2
by: Samuel R. Neff | last post by:
I'm trying to find a good way to handle Control.InvokeRequired without duplicating four lines of code in every function/event. Typically what I've seen in books is this: If InvokeRequired Then...
5
by: Michael C# | last post by:
Hi all, I set up a System.Timers.Time in my app. The code basically just updates the screen, but since the processing performed is so CPU-intensive, I wanted to make sure it gets updated...
1
by: Mesan | last post by:
I'm getting a "Cross-thread operation not valid" Exception and I can't figure out why. I've got a BackgroundWorker that creates a UserControl with a whole lot of other user controls inside of...
1
by: Mark Denardo | last post by:
Hey all, I'm having a problem with the following: Private m_myDELEGATE As New myDELEGATE(AddressOf ReceivingServerMessage_UIThread) Delegate Sub myDELEGATE(ByVal ReceivingServerMessage As...
4
by: Bill McCormick | last post by:
Hello, A timer control (I think) runs in another thread apart from a main form. In the OnTick event, you can update some form control with no worries. I'm making an AsyncronousServer class...
4
by: =?Utf-8?B?R3V5IENvaGVu?= | last post by:
Hi all I wrote a small demo program to understand timers and delegation - and its working fine. However, I would like to use the timer in a DLL(Class) When I compile the code: Protected...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.