By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,403 Members | 855 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,403 IT Pros & Developers. It's quick & easy.

Yet another threading/invoking question...

P: n/a
Hi,

I'm currently rewriting some functionality which was using
multithredaing for retrieving datasets from database and updating a grid
control. I found that the grids (Infragistics UltraGrid, though it
doesn't matter) were updated (i.e. grid.DataSource = dsDataSet;) and
used for different purposes in the worker thread, so now i'm wrapping
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted
to see if for now i could leave some of those calls as is.

So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;

from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call?

Consider this sample:

// Somewhere in the UI (main) thread:
mygridcontrol = new UltraGrid();
Thread t = new Thread(new ThreadStarter(UpdateFuncDelegate));
.... and no code after that...
// In wroker thread - in function UpdateFunc

object o = mygridcontrol.Tag;

//////////////////////////

I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?
Thank you!
MuZZy
Dec 23 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a
MuZZy <tn*@newsgroups.nospam> wrote:

<snip>
I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?


I wouldn't like to say for sure whether it will lead to an error. I'd
have thought the fact that you know you shouldn't do it would be enough
to make you not do it, however. After all, even if it works in test,
you could easily get an issue on a customer box, by which time it's too
late to do it properly.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #2

P: n/a
> from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call? Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?
[in my opinion]: I think its not only "your code" that you can check and
guarantee wont touch the grid while your worker thread is updating it. It
could be windows framework's code accessing your grid at a time you dont
anticipate, like painting the grid. I'm not sure that it really happens what
I said about painting grid by the framework, but I'm sure things like this
happens and thats why people have problems while they access there UI
controls from other than there owning thread cuz "some times" that code
works and "sometimes" it doesnt. But thats what happen in race conditions,
sometimes they arise and sometimes they dont. So why not follow the discrete
rules and do yourself a favor by doing the invoking work that u r doing
right now. It'll benifit you in the future. As Jon said, your code may not
work on your customer's box. Imagine what will happen than.
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted
also you dont have to call "all" the methods of the grid in the working
thread, try changing some logic, like just call one function through invoke
and there do the rest.

Ab.

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:un**************@TK2MSFTNGP09.phx.gbl... Hi,

I'm currently rewriting some functionality which was using
multithredaing for retrieving datasets from database and updating a grid
control. I found that the grids (Infragistics UltraGrid, though it
doesn't matter) were updated (i.e. grid.DataSource = dsDataSet;) and
used for different purposes in the worker thread, so now i'm wrapping
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted
to see if for now i could leave some of those calls as is.

So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;

from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call?

Consider this sample:

// Somewhere in the UI (main) thread:
mygridcontrol = new UltraGrid();
Thread t = new Thread(new ThreadStarter(UpdateFuncDelegate));
... and no code after that...
// In wroker thread - in function UpdateFunc

object o = mygridcontrol.Tag;

//////////////////////////

I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?
Thank you!
MuZZy

Dec 23 '05 #3

P: n/a
Hi,
So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;


What is wrong with that? IF this call is made after the binding you should
get your value correctly, I do not think that Tag changes after a binding.

What you cannot do frmo a thread is the opposite:

mygridcontrol.Tag = o;
Then is when you can get problems
BTW, what does UltraGrid.Tag returns?


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Dec 23 '05 #4

P: n/a
but I'm sure things like this
happens and thats why people have problems while they access there UI
controls from other than there owning thread cuz "some times" that code
works and "sometimes" it doesnt.


Correct me if I'm wrong, but this is only a problem when you make a change
to the control, cause this change will probably provoke a visually change
and this is where the problem is, trying to access the UI from a worker
thread.
Reading a property of a control instance frmo a different thread is safe
(it will not block the UI), as long as accessing any other variable is.
Especially if you know this variable does not change of value once it's
assigned.


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Dec 23 '05 #5

P: n/a
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;


What is wrong with that? IF this call is made after the binding you should
get your value correctly, I do not think that Tag changes after a binding.

What you cannot do frmo a thread is the opposite:

mygridcontrol.Tag = o;

Then is when you can get problems


No - strictly speaking, your not meant to even *access* properties on a
non-UI thread. In this case it would *probably* be okay, but I
certainly wouldn't want to risk it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #6

P: n/a
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
but I'm sure things like this
happens and thats why people have problems while they access there UI
controls from other than there owning thread cuz "some times" that code
works and "sometimes" it doesnt.


Correct me if I'm wrong, but this is only a problem when you make a change
to the control, cause this change will probably provoke a visually change
and this is where the problem is, trying to access the UI from a worker
thread.
Reading a property of a control instance frmo a different thread is safe
(it will not block the UI), as long as accessing any other variable is.
Especially if you know this variable does not change of value once it's
assigned.


Blocking the UI isn't a problem - it's using *any* member which isn't
explicitly marked as being thread-safe which is the problem.

Without knowing the guts of how the Tag property is implemented, it's
very difficult to say for *certain* whether it's safe to access it from
another thread.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #7

P: n/a
Hi,

No - strictly speaking, your not meant to even *access* properties on a
non-UI thread. In this case it would *probably* be okay, but I
certainly wouldn't want to risk it.

Do you have a concrete example of accesing a property of one of the stock
controls can create problems?

It should only matters if the accesor makes some changes in the internal
status of the object.

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Dec 23 '05 #8

P: n/a
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
No - strictly speaking, your not meant to even *access* properties on a
non-UI thread. In this case it would *probably* be okay, but I
certainly wouldn't want to risk it.
Do you have a concrete example of accesing a property of one of the stock
controls can create problems?


Not off-hand - but the documentation for Control clearly states:

<quote>
Only the following members are thread safe: BeginInvoke, EndInvoke,
Invoke, InvokeRequired, and CreateGraphics.
</quote>

If the accessors were guaranteed to be thread-safe, I'd have expected
that to be documented too.
It should only matters if the accesor makes some changes in the internal
status of the object.


Or if the accessor uses some internal state which may be in the process
of changing while it is being accessed...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #9

P: n/a
Everything boils down to one simple rule: "don't modify "window objects"
associated with a Window Handle (HWND) from another thread than the thread
that owns the Handle (the creator of the window class).
Or otherwise stated, "Window Handles" have thread affinity. That means that
only the creator thread should modify the associated UI element, but , and
this answers your question, other threads are allowed to read properties,
styles and other attributes in a thread safe manner.
Note however that in v2, a cross thread exception will get thrown (debug
build) even if you read properties from the non owning thread, IMO this is
too restrictive, but I know why it's been done that way.
UI objects that do not have thread affinity are, menus, icons and cursors,
here again multiple threads may access them but you need to coordinate
accesses (you may not modify a menu while another thread is displaying it).

Willy.

"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:O2**************@TK2MSFTNGP15.phx.gbl...
Hi,
So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;


What is wrong with that? IF this call is made after the binding you should
get your value correctly, I do not think that Tag changes after a binding.

What you cannot do frmo a thread is the opposite:

mygridcontrol.Tag = o;
Then is when you can get problems
BTW, what does UltraGrid.Tag returns?


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

Dec 23 '05 #10

P: n/a
Willy Denoyette [MVP] wrote:
Everything boils down to one simple rule: "don't modify "window objects"
associated with a Window Handle (HWND) from another thread than the thread
that owns the Handle (the creator of the window class).
Or otherwise stated, "Window Handles" have thread affinity. That means that
only the creator thread should modify the associated UI element, but , and
this answers your question, other threads are allowed to read properties,
styles and other attributes in a thread safe manner.
Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.

Note however that in v2, a cross thread exception will get thrown (debug
build) even if you read properties from the non owning thread, IMO this is
too restrictive, but I know why it's been done that way.
UI objects that do not have thread affinity are, menus, icons and cursors,
here again multiple threads may access them but you need to coordinate
accesses (you may not modify a menu while another thread is displaying it).

Willy.

"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:O2**************@TK2MSFTNGP15.phx.gbl...
Hi,
So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;

What is wrong with that? IF this call is made after the binding you should
get your value correctly, I do not think that Tag changes after a binding.

What you cannot do frmo a thread is the opposite:

mygridcontrol.Tag = o;
Then is when you can get problems
BTW, what does UltraGrid.Tag returns?


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Dec 23 '05 #11

P: n/a
Jon Skeet [C# MVP] wrote:
MuZZy <tn*@newsgroups.nospam> wrote:

<snip>
I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?


I wouldn't like to say for sure whether it will lead to an error. I'd
have thought the fact that you know you shouldn't do it would be enough
to make you not do it, however. After all, even if it works in test,
you could easily get an issue on a customer box, by which time it's too
late to do it properly.


That has actually happened on a customer box, that's how i came across
this problem... It's better to do it right late than never :)

MuZZy
Dec 23 '05 #12

P: n/a
Abubakar wrote:
from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call?
Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?


[in my opinion]: I think its not only "your code" that you can check and
guarantee wont touch the grid while your worker thread is updating it. It
could be windows framework's code accessing your grid at a time you dont
anticipate, like painting the grid. I'm not sure that it really happens what
I said about painting grid by the framework, but I'm sure things like this
happens and thats why people have problems while they access there UI
controls from other than there owning thread cuz "some times" that code
works and "sometimes" it doesnt. But thats what happen in race conditions,
sometimes they arise and sometimes they dont. So why not follow the discrete
rules and do yourself a favor by doing the invoking work that u r doing
right now. It'll benifit you in the future. As Jon said, your code may not
work on your customer's box. Imagine what will happen than.


I agree. It's just that yesterday when i was looking at the whole code
and realized that i need to re-do the whole Worker thread/UI controls
interaction i got a bit overwhelmed, but now after a sleepless night it
seems like a solvable task. I have to change some logic here and there
to make number of different calls from Worker thread to UI limited and
also in some cases i will have to use synchronous invocation but overall
it now doesn't seem as scary as yesterday :)
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted


also you dont have to call "all" the methods of the grid in the working
thread, try changing some logic, like just call one function through invoke
and there do the rest.

Ab.

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:un**************@TK2MSFTNGP09.phx.gbl...
Hi,

I'm currently rewriting some functionality which was using
multithredaing for retrieving datasets from database and updating a grid
control. I found that the grids (Infragistics UltraGrid, though it
doesn't matter) were updated (i.e. grid.DataSource = dsDataSet;) and
used for different purposes in the worker thread, so now i'm wrapping
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted
to see if for now i could leave some of those calls as is.

So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;

from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call?

Consider this sample:

// Somewhere in the UI (main) thread:
mygridcontrol = new UltraGrid();
Thread t = new Thread(new ThreadStarter(UpdateFuncDelegate));
... and no code after that...
// In wroker thread - in function UpdateFunc

object o = mygridcontrol.Tag;

//////////////////////////

I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?
Thank you!
MuZZy


Dec 23 '05 #13

P: n/a
MuZZy wrote:
Hi,

I'm currently rewriting some functionality which was using
multithredaing for retrieving datasets from database and updating a grid
control. I found that the grids (Infragistics UltraGrid, though it
doesn't matter) were updated (i.e. grid.DataSource = dsDataSet;) and
used for different purposes in the worker thread, so now i'm wrapping
all those calls to grid's methods thru invoking which is a pain in the
a$$ considering number of different methods UltraGrid has. So i wanted
to see if for now i could leave some of those calls as is.

So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;

from a worker thread even if i am 100% sure this "mygridcontrol" is not
going to be used in the UI thread at the same time as i make this call?

Consider this sample:

// Somewhere in the UI (main) thread:
mygridcontrol = new UltraGrid();
Thread t = new Thread(new ThreadStarter(UpdateFuncDelegate));
... and no code after that...
// In wroker thread - in function UpdateFunc

object o = mygridcontrol.Tag;

//////////////////////////

I know it's really bad bad bad!!! But still...

Please don't tell me i shouldn't do that, i know that.
Just tell me - if control is not used at time when its method is called
from a worker thread - is it going to lead to an error or not?
And if yes, why?
Thank you!
MuZZy

Thank you all guys for your replies, now i have a concrete picture.

Actually one more question - is it anyhow different for UI thread if i
use sync invocation (Control.Invoke) instead of async one
(Control.BeginIinvoke). I know it will block the worker thread, but i
don't think it will be any different for UI thread, right?

And again, thanks for all you comments
MuZZy

Dec 23 '05 #14

P: n/a
Ignacio Machin ( .NET/ C# MVP ) wrote:
Hi,
So my question is: is it really-really... and i mean REALLY bad to call:

object o = mygridcontrol.Tag;


What is wrong with that? IF this call is made after the binding you should
get your value correctly, I do not think that Tag changes after a binding.

What you cannot do frmo a thread is the opposite:

mygridcontrol.Tag = o;
Then is when you can get problems
BTW, what does UltraGrid.Tag returns?


It's Control.Tag :)
Dec 23 '05 #15

P: n/a

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...
Willy Denoyette [MVP] wrote:
Everything boils down to one simple rule: "don't modify "window objects"
associated with a Window Handle (HWND) from another thread than the
thread that owns the Handle (the creator of the window class).
Or otherwise stated, "Window Handles" have thread affinity. That means
that only the creator thread should modify the associated UI element, but
, and this answers your question, other threads are allowed to read
properties, styles and other attributes in a thread safe manner.


Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.


Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component in
user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's "Text"
property. The way this is done is by calling user32 "GetWindowText" API.
This API takes the HWND of the Label control a pointer to a buffer that will
hold the test of the label after success return and the length of the
buffer. The function sends a WM_GETTEXT window message to the owning thread
message queue (the Handle<->thread relation is maintained by the window
manager - thread affinity remember!), where it will be handled by the
WndProc. That means that an 'update' of the label can never "interfere" with
a 'read' of the text (a string), so it's thread safe right? !!Note that this
doesn't apply to simultaneous updates!!
Now, back to Windows.Forms. You know that WF sits in top of Win32 or in top
of user32's provided window services. So what WF does to read a Text
property from a Label is exactly what I described above, but it does more.
It can cache (some) properties in an internal cache to speed up fetches.
Accesses to the internal cache are not synchronized by the framework (it
would defeat the purpose of the caching), that means it's not 'thread safe'
to access them from multiple threads, this is not such a problem other than
you may read old or inconsistent data from a control, but it will never
cause deadlocks as is the case with multiple updates of UI control elements.
However, as I said before, v2 of the framework will throw an exception if
you read a property from a non-owning thread (see my previous reply).

Willy.


Dec 23 '05 #16

P: n/a
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...
Willy Denoyette [MVP] wrote:
Everything boils down to one simple rule: "don't modify "window objects"
associated with a Window Handle (HWND) from another thread than the
thread that owns the Handle (the creator of the window class).
Or otherwise stated, "Window Handles" have thread affinity. That means
that only the creator thread should modify the associated UI element, but
, and this answers your question, other threads are allowed to read
properties, styles and other attributes in a thread safe manner. Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.


Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component in
user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's "Text"
property. The way this is done is by calling user32 "GetWindowText" API.
This API takes the HWND of the Label control a pointer to a buffer that will
hold the test of the label after success return and the length of the
buffer. The function sends a WM_GETTEXT window message to the owning thread
message queue (the Handle<->thread relation is maintained by the window
manager - thread affinity remember!), where it will be handled by the
WndProc.


What you describe here for Win32 processes is exactly what happens when
i call .NET's Control.Invoke/BeginInvoke - it sends a message via
blocking PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

.... instead of

bool bVisible = button.Visible;

Right?
Only in this case you can guarantee that you request doesn't get any
inconsistent data
That means that an 'update' of the label can never "interfere" with
a 'read' of the text (a string), so it's thread safe right? !!Note that this
doesn't apply to simultaneous updates!!
Now, back to Windows.Forms. You know that WF sits in top of Win32 or in top
of user32's provided window services. So what WF does to read a Text
property from a Label is exactly what I described above, but it does more.
It can cache (some) properties in an internal cache to speed up fetches.
Accesses to the internal cache are not synchronized by the framework (it
would defeat the purpose of the caching), that means it's not 'thread safe'
to access them from multiple threads, this is not such a problem other than
you may read old or inconsistent data from a control, but it will never
cause deadlocks as is the case with multiple updates of UI control elements.
However, as I said before, v2 of the framework will throw an exception if
you read a property from a non-owning thread (see my previous reply).

Willy.


Dec 23 '05 #17

P: n/a

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...
Willy Denoyette [MVP] wrote:
Everything boils down to one simple rule: "don't modify "window
objects" associated with a Window Handle (HWND) from another thread
than the thread that owns the Handle (the creator of the window class).
Or otherwise stated, "Window Handles" have thread affinity. That means
that only the creator thread should modify the associated UI element,
but , and this answers your question, other threads are allowed to read
properties, styles and other attributes in a thread safe manner.
Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.
Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component
in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's
"Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after success
return and the length of the buffer. The function sends a WM_GETTEXT
window message to the owning thread message queue (the Handle<->thread
relation is maintained by the window manager - thread affinity
remember!), where it will be handled by the WndProc.


What you describe here for Win32 processes is exactly what happens when i
call .NET's Control.Invoke/BeginInvoke - it sends a message via blocking
PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?


Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will call
the delegate target on it's own (correct) thread. What I described above
skips the first SendMesage and uses a single SendMessage to send WM_XXX
messages to retrieve the property. That means it is inherently faster.
Note again that this is no longer possible in V2 of the framework, but it's
how it can safely be done using the Win32 API's (and the native frameworks
like MFC, WFC and ATL).
Only in this case you can guarantee that you request doesn't get any
inconsistent data


Correct. But see above.

Willy.
Dec 23 '05 #18

P: n/a
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...
Willy Denoyette [MVP] wrote:
> Everything boils down to one simple rule: "don't modify "window
> objects" associated with a Window Handle (HWND) from another thread
> than the thread that owns the Handle (the creator of the window class).
> Or otherwise stated, "Window Handles" have thread affinity. That means
> that only the creator thread should modify the associated UI element,
> but , and this answers your question, other threads are allowed to read
> properties, styles and other attributes in a thread safe manner.
Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.
Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component
in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's
"Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after success
return and the length of the buffer. The function sends a WM_GETTEXT
window message to the owning thread message queue (the Handle<->thread
relation is maintained by the window manager - thread affinity
remember!), where it will be handled by the WndProc.

What you describe here for Win32 processes is exactly what happens when i
call .NET's Control.Invoke/BeginInvoke - it sends a message via blocking
PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?


Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will call
the delegate target on it's own (correct) thread. What I described above
skips the first SendMesage and uses a single SendMessage to send WM_XXX
messages to retrieve the property. That means it is inherently faster.
Note again that this is no longer possible in V2 of the framework, but it's
how it can safely be done using the Win32 API's (and the native frameworks
like MFC, WFC and ATL).


Wow, wow hold on! What is "no longer possible in V2 of the framework" -
using Control.Invoke? Then i'll go hang on the tree, because i just
spent 10 hours in a row wrapping calls to controls using BeginInvoke.

Or did i miss something?

Only in this case you can guarantee that you request doesn't get any
inconsistent data


Correct. But see above.

Willy.

Dec 23 '05 #19

P: n/a
I just want to add to it, that you can check the .NET code of the stock
controls using reflector, but all that you'll get out of it is the fact
that many methods/properties end up as WinAPI calls. From there, it's
absolutely hopeless to try and analyse what will happen when you call
these from different threads. I remember having terrible problems in my
MFC days with GetWindowText and the likes, until I have learned that you
have to marshall calls to the UI thread to this (which was lots of fun
back then).

Just my 2c.
Stefan

Jon Skeet [C# MVP] wrote:
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
No - strictly speaking, your not meant to even *access* properties on a
non-UI thread. In this case it would *probably* be okay, but I
certainly wouldn't want to risk it.


Do you have a concrete example of accesing a property of one of the stock
controls can create problems?

Not off-hand - but the documentation for Control clearly states:

<quote>
Only the following members are thread safe: BeginInvoke, EndInvoke,
Invoke, InvokeRequired, and CreateGraphics.
</quote>

If the accessors were guaranteed to be thread-safe, I'd have expected
that to be documented too.

It should only matters if the accesor makes some changes in the internal
status of the object.

Or if the accessor uses some internal state which may be in the process
of changing while it is being accessed...

Dec 23 '05 #20

P: n/a
Please correct me if I'm wrong, but AFAIK, SendMessage doesn't do any
marshalling to the owner's thread, it sort of directly calls the
window's WndProc. It's terribly unsafe to SendMessage anything from
another thread.

Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...

Willy Denoyette [MVP] wrote:

>Everything boils down to one simple rule: "don't modify "window
>objects" associated with a Window Handle (HWND) from another thread
>than the thread that owns the Handle (the creator of the window class).
>Or otherwise stated, "Window Handles" have thread affinity. That means
>that only the creator thread should modify the associated UI element,
>but , and this answers your question, other threads are allowed to read
>properties, styles and other attributes in a thread safe manner.

Hm... how can you make sure you access a UI control's property/attribute
from a worker thread in a "thread safe" way other than using
Control.Invoke/BeginInvoke? There is no way you could know from a worker
thread that the UI control is not being modified right this moment and
calling a property's getter will not give you a wrong result.

Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component
in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's
"Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after success
return and the length of the buffer. The function sends a WM_GETTEXT
window message to the owning thread message queue (the Handle<->thread
relation is maintained by the window manager - thread affinity
remember!), where it will be handled by the WndProc.


What you describe here for Win32 processes is exactly what happens when i
call .NET's Control.Invoke/BeginInvoke - it sends a message via blocking
PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?

Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will call
the delegate target on it's own (correct) thread. What I described above
skips the first SendMesage and uses a single SendMessage to send WM_XXX
messages to retrieve the property. That means it is inherently faster.
Note again that this is no longer possible in V2 of the framework, but it's
how it can safely be done using the Win32 API's (and the native frameworks
like MFC, WFC and ATL).

Only in this case you can guarantee that you request doesn't get any
inconsistent data

Correct. But see above.

Willy.

Dec 23 '05 #21

P: n/a
MuZZy wrote:
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...

> Willy Denoyette [MVP] wrote:
>
>> Everything boils down to one simple rule: "don't modify "window
>> objects" associated with a Window Handle (HWND) from another
>> thread than the thread that owns the Handle (the creator of the
>> window class).
>> Or otherwise stated, "Window Handles" have thread affinity. That
>> means that only the creator thread should modify the associated UI
>> element, but , and this answers your question, other threads are
>> allowed to read properties, styles and other attributes in a
>> thread safe manner.
>
> Hm... how can you make sure you access a UI control's
> property/attribute from a worker thread in a "thread safe" way
> other than using Control.Invoke/BeginInvoke? There is no way you
> could know from a worker thread that the UI control is not being
> modified right this moment and calling a property's getter will not
> give you a wrong result.
>
>
Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note
the "Window" ...
This is true from the Window Manager's point of view (a native
component in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get
it's "Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after
success return and the length of the buffer. The function sends a
WM_GETTEXT window message to the owning thread message queue (the
Handle<->thread relation is maintained by the window manager -
thread affinity remember!), where it will be handled by the WndProc.

What you describe here for Win32 processes is exactly what happens
when i call .NET's Control.Invoke/BeginInvoke - it sends a message
via blocking PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?

Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message
queue and it puts a delegate in a private queue that will get fetched
by the WndProc when it processes the "private user message". The
WndProc will call the delegate target on it's own (correct) thread.
What I described above skips the first SendMesage and uses a single
SendMessage to send WM_XXX messages to retrieve the property. That
means it is inherently faster.
Note again that this is no longer possible in V2 of the framework, but
it's how it can safely be done using the Win32 API's (and the native
frameworks like MFC, WFC and ATL).

Wow, wow hold on! What is "no longer possible in V2 of the framework" -
using Control.Invoke? Then i'll go hang on the tree, because i just
spent 10 hours in a row wrapping calls to controls using BeginInvoke.

Or did i miss something?

Only in this case you can guarantee that you request doesn't get any
inconsistent data


Correct. But see above.

Willy.

The 2.0 framework complains (in debug builds) about calls from non-UI
threads to control methods. This has nothing to do with
Control.Invoke/BeginInvoke (the methods wouldn't be of much use, if you
couldn't use them from any thread, would they?)

Stefan
Dec 23 '05 #22

P: n/a
No, SendMessage does marshaling for system messages(0-WM_USER), other
message types must be custom marshaled (think Control.Invoke/BeginInvoke).
The WndProc is only called directly (as a subroutine) when the SendMessage
thread is the same as the HWND owned thread (the one that created the
window), otherwise the system switches to the owning thread and puts thye
message into it's message queue where it will be picked-up by the right
thread's WndProc.
Please consult SendMessage API for more details.

Willy.

"Stefan Simek" <si**********@triaxis.nospam.sk> wrote in message
news:OL***************@TK2MSFTNGP14.phx.gbl...
Please correct me if I'm wrong, but AFAIK, SendMessage doesn't do any
marshalling to the owner's thread, it sort of directly calls the window's
WndProc. It's terribly unsafe to SendMessage anything from another thread.

Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...

>Willy Denoyette [MVP] wrote:
>
>>Everything boils down to one simple rule: "don't modify "window
>>objects" associated with a Window Handle (HWND) from another thread
>>than the thread that owns the Handle (the creator of the window
>>class).
>>Or otherwise stated, "Window Handles" have thread affinity. That means
>>that only the creator thread should modify the associated UI element,
>>but , and this answers your question, other threads are allowed to
>>read properties, styles and other attributes in a thread safe manner.
>
>Hm... how can you make sure you access a UI control's
>property/attribute from a worker thread in a "thread safe" way other
>than using Control.Invoke/BeginInvoke? There is no way you could know
>from a worker thread that the UI control is not being modified right
>this moment and calling a property's getter will not give you a wrong
>result.
>
>

Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native component
in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's
"Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after success
return and the length of the buffer. The function sends a WM_GETTEXT
window message to the owning thread message queue (the Handle<->thread
relation is maintained by the window manager - thread affinity
remember!), where it will be handled by the WndProc.

What you describe here for Win32 processes is exactly what happens when i
call .NET's Control.Invoke/BeginInvoke - it sends a message via blocking
PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?

Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will
call the delegate target on it's own (correct) thread. What I described
above skips the first SendMesage and uses a single SendMessage to send
WM_XXX messages to retrieve the property. That means it is inherently
faster.
Note again that this is no longer possible in V2 of the framework, but
it's how it can safely be done using the Win32 API's (and the native
frameworks like MFC, WFC and ATL).

Only in this case you can guarantee that you request doesn't get any
inconsistent data

Correct. But see above.

Willy.


Dec 23 '05 #23

P: n/a

"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:e7****************@tk2msftngp13.phx.gbl...
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:O$*************@TK2MSFTNGP15.phx.gbl...
> Willy Denoyette [MVP] wrote:
>> Everything boils down to one simple rule: "don't modify "window
>> objects" associated with a Window Handle (HWND) from another thread
>> than the thread that owns the Handle (the creator of the window
>> class).
>> Or otherwise stated, "Window Handles" have thread affinity. That
>> means that only the creator thread should modify the associated UI
>> element, but , and this answers your question, other threads are
>> allowed to read properties, styles and other attributes in a thread
>> safe manner.
> Hm... how can you make sure you access a UI control's
> property/attribute from a worker thread in a "thread safe" way other
> than using Control.Invoke/BeginInvoke? There is no way you could know
> from a worker thread that the UI control is not being modified right
> this moment and calling a property's getter will not give you a wrong
> result.
>
>
Note I should have been more explicit, what I meant was:
"other threads are allowed to read 'Window properties',
'Window styles' and other attributes in a thread safe manner." Note the
"Window" ...
This is true from the Window Manager's point of view (a native
component in user32.dll).
Let me explain with a sample.
Suppose you have a form with 'Label' control and you want to get it's
"Text" property. The way this is done is by calling user32
"GetWindowText" API. This API takes the HWND of the Label control a
pointer to a buffer that will hold the test of the label after success
return and the length of the buffer. The function sends a WM_GETTEXT
window message to the owning thread message queue (the Handle<->thread
relation is maintained by the window manager - thread affinity
remember!), where it will be handled by the WndProc.
What you describe here for Win32 processes is exactly what happens when
i call .NET's Control.Invoke/BeginInvoke - it sends a message via
blocking PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?


Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will
call the delegate target on it's own (correct) thread. What I described
above skips the first SendMesage and uses a single SendMessage to send
WM_XXX messages to retrieve the property. That means it is inherently
faster.
Note again that this is no longer possible in V2 of the framework, but
it's how it can safely be done using the Win32 API's (and the native
frameworks like MFC, WFC and ATL).


Wow, wow hold on! What is "no longer possible in V2 of the framework" -
using Control.Invoke? Then i'll go hang on the tree, because i just spent
10 hours in a row wrapping calls to controls using BeginInvoke.

Or did i miss something?


I'm not talking about Control.Invoke/BeginInvoke, I was talking about
accessing window properties directly from a non owning thread.

Something like:
// read Text property from non label1 owning thread
string lblTest = label1.Text;
Willy.
Dec 23 '05 #24

P: n/a
Thanks a lot, I should have read the documentation before I posted...

Willy Denoyette [MVP] wrote:
No, SendMessage does marshaling for system messages(0-WM_USER), other
message types must be custom marshaled (think Control.Invoke/BeginInvoke).
The WndProc is only called directly (as a subroutine) when the SendMessage
thread is the same as the HWND owned thread (the one that created the
window), otherwise the system switches to the owning thread and puts thye
message into it's message queue where it will be picked-up by the right
thread's WndProc.
Please consult SendMessage API for more details.

Willy.

"Stefan Simek" <si**********@triaxis.nospam.sk> wrote in message
news:OL***************@TK2MSFTNGP14.phx.gbl...
Please correct me if I'm wrong, but AFAIK, SendMessage doesn't do any
marshalling to the owner's thread, it sort of directly calls the window's
WndProc. It's terribly unsafe to SendMessage anything from another thread.

Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl. ..
Willy Denoyette [MVP] wrote:
>"MuZZy" <tn*@newsgroups.nospam> wrote in message
>news:O$*************@TK2MSFTNGP15.phx.gbl.. .
>
>
>>Willy Denoyette [MVP] wrote:
>>
>>
>>>Everything boils down to one simple rule: "don't modify "window
>>>objects" associated with a Window Handle (HWND) from another thread
>>>than the thread that owns the Handle (the creator of the window
>>>class).
>>>Or otherwise stated, "Window Handles" have thread affinity. That means
>>>that only the creator thread should modify the associated UI element,
>>>but , and this answers your question, other threads are allowed to
>>>read properties, styles and other attributes in a thread safe manner.
>>
>>Hm... how can you make sure you access a UI control's
>>property/attribute from a worker thread in a "thread safe" way other
>>than using Control.Invoke/BeginInvoke? There is no way you could know
>
>>from a worker thread that the UI control is not being modified right
>
>>this moment and calling a property's getter will not give you a wrong
>>result.
>>
>>
>
>Note I should have been more explicit, what I meant was:
>"other threads are allowed to read 'Window properties',
>'Window styles' and other attributes in a thread safe manner." Note the
>"Window" ...
>This is true from the Window Manager's point of view (a native component
>in user32.dll).
>Let me explain with a sample.
>Suppose you have a form with 'Label' control and you want to get it's
>"Text" property. The way this is done is by calling user32
>"GetWindowText" API. This API takes the HWND of the Label control a
>pointer to a buffer that will hold the test of the label after success
>return and the length of the buffer. The function sends a WM_GETTEXT
>window message to the owning thread message queue (the Handle<->thread
>relation is maintained by the window manager - thread affinity
>remember!), where it will be handled by the WndProc.

What you describe here for Win32 processes is exactly what happens when i
call .NET's Control.Invoke/BeginInvoke - it sends a message via blocking
PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?
Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message queue
and it puts a delegate in a private queue that will get fetched by the
WndProc when it processes the "private user message". The WndProc will
call the delegate target on it's own (correct) thread. What I described
above skips the first SendMesage and uses a single SendMessage to send
WM_XXX messages to retrieve the property. That means it is inherently
faster.
Note again that this is no longer possible in V2 of the framework, but
it's how it can safely be done using the Win32 API's (and the native
frameworks like MFC, WFC and ATL).

Only in this case you can guarantee that you request doesn't get any
inconsistent data

Correct. But see above.

Willy.


Dec 23 '05 #25

P: n/a
Stefan Simek wrote:
MuZZy wrote:
Willy Denoyette [MVP] wrote:
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eX****************@TK2MSFTNGP11.phx.gbl...

Willy Denoyette [MVP] wrote:

> "MuZZy" <tn*@newsgroups.nospam> wrote in message
> news:O$*************@TK2MSFTNGP15.phx.gbl...
>
>> Willy Denoyette [MVP] wrote:
>>
>>> Everything boils down to one simple rule: "don't modify "window
>>> objects" associated with a Window Handle (HWND) from another
>>> thread than the thread that owns the Handle (the creator of the
>>> window class).
>>> Or otherwise stated, "Window Handles" have thread affinity. That
>>> means that only the creator thread should modify the associated
>>> UI element, but , and this answers your question, other threads
>>> are allowed to read properties, styles and other attributes in a
>>> thread safe manner.
>>
>> Hm... how can you make sure you access a UI control's
>> property/attribute from a worker thread in a "thread safe" way
>> other than using Control.Invoke/BeginInvoke? There is no way you
>> could know from a worker thread that the UI control is not being
>> modified right this moment and calling a property's getter will
>> not give you a wrong result.
>>
>>
> Note I should have been more explicit, what I meant was:
> "other threads are allowed to read 'Window properties',
> 'Window styles' and other attributes in a thread safe manner." Note
> the "Window" ...
> This is true from the Window Manager's point of view (a native
> component in user32.dll).
> Let me explain with a sample.
> Suppose you have a form with 'Label' control and you want to get
> it's "Text" property. The way this is done is by calling user32
> "GetWindowText" API. This API takes the HWND of the Label control a
> pointer to a buffer that will hold the test of the label after
> success return and the length of the buffer. The function sends a
> WM_GETTEXT window message to the owning thread message queue (the
> Handle<->thread relation is maintained by the window manager -
> thread affinity remember!), where it will be handled by the WndProc.

What you describe here for Win32 processes is exactly what happens
when i call .NET's Control.Invoke/BeginInvoke - it sends a message
via blocking PostMessage or non-blocking SendMessage.

So you are talking about getting properties/attributes using
Control.Invoke, not obtaining them directly, eg

bool bVisible = button.Invoke(CheckVisibleDelegate);

... instead of

bool bVisible = button.Visible;

Right?
Well, almost, what Invoke/BeginInvoke does is using SendMessage or
PostMessage to pass a "private user message" to the windows message
queue and it puts a delegate in a private queue that will get fetched
by the WndProc when it processes the "private user message". The
WndProc will call the delegate target on it's own (correct) thread.
What I described above skips the first SendMesage and uses a single
SendMessage to send WM_XXX messages to retrieve the property. That
means it is inherently faster.
Note again that this is no longer possible in V2 of the framework,
but it's how it can safely be done using the Win32 API's (and the
native frameworks like MFC, WFC and ATL).

Wow, wow hold on! What is "no longer possible in V2 of the framework"
- using Control.Invoke? Then i'll go hang on the tree, because i just
spent 10 hours in a row wrapping calls to controls using BeginInvoke.

Or did i miss something?

Only in this case you can guarantee that you request doesn't get any
inconsistent data
Correct. But see above.

Willy.

The 2.0 framework complains (in debug builds) about calls from non-UI
threads to control methods.


And that's cool - i hope it will stop some brickheads in our department
from making me fix their code :)
This has nothing to do with
Control.Invoke/BeginInvoke (the methods wouldn't be of much use, if you
couldn't use them from any thread, would they?)


That's why i was surprised...
Dec 23 '05 #26

This discussion thread is closed

Replies have been disabled for this discussion.