Threadsafe operations

  • Thread starter Thread starter Ayende Rahien
  • Start date Start date
A

Ayende Rahien

How do I create thread safe functions similiar to this one without using
WinForms?

private void UpdateText(string Text)
{
if(SomeControl.InvokeRequired)
{
SomeControl.Invoke(new MethodStringInvoker(UpdateText),new object[]{Text});
}
else
{
SomeControl.Text = Text;
}
}
 
Hi Ayende,
If you want to execute code in another already running thread IMHO you
can't. WinForms uses windows message queue to switch the executing thread.
It can do that because it is event driven framework.
If you wright a class representing event driven thread you may be able to
achieve the same functioanlity or if the code executed in the worker thread
expects and checks for such a requests.

B\rgds
100
 
The real answer is "it depends".

First, an assumption: I am assuming that you have some object that will be
interacting with a form -- so you need for all of your synchronized activity
to occur on the same thread as the target form. Is this correct? (if not,
you can ignore the rest of this post).

A form has the InvokeRequired/Invoke methods because it implements
ISynchronizeInvoke. Now, just the other day, I saw an article by Juval
Lowey (sincere appologies if I spelled his name incorrectly) which I believe
included source for doing your own ISynchronizeInvoke implementation. I
didn't read it, but he remarked that it was "nontrivial". If you want to
search for it, I'm pretty sure that it was an MSDN magazine article on
msdn.microsoft.com

Now, if you simply have a component that is supposed to service a form,
there is a way to work with the invoke stuff. I don't know whether this
pattern fits your needs or not, but I did come across a need that sounds
similar.

In my case, I wanted to implement a sort of strategy pattern, so I wanted
to move some UI-affecting logic out of a form and into a component that
would service the form. Usually, the component was affecting a form, but it
could be used by a non-UI item as well (it's just fetching some data on a
background thread).

I created a member on the component:
ISynchronizeInvoke SynchronizationRoot;

since Form implements this, it'll work with a form, or any future construct
that uses the Invoke pattern (perhaps one of my own design, even)

If a form is using my strategy component, it assigns itself to this member.
Then, in my component code that checks for invoke required, I do something
like this (watch for typos):
if(this.SynchronizationRoot != null &&
this.SynchronizationRoot.InvokeRequired)
this.SynchronizationRoot.Invoke(..)
else
// just do it

If the component is not servicing a form, SynchronizationRoot will be null,
so it won't bother with the sync (now, you still have to watch thread
safety -- if you're acting on shared data, you still might have to implment
locking)
 
Back
Top