Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multithreading and updating the GUI

2 views
Skip to first unread message

b

unread,
Jun 24, 2008, 3:59:44 PM6/24/08
to
Hi all,

I have a workerthread which notyfies the GUI through a delegate like this:

if (deviceInsertedDelegate) deviceInsertedDelegate(stringAddress);

Now in my Form's code I write code like this:

private delegate void DeviceInsertedCallback(string Address);

public void DeviceInserted(string Address)
{
if (this.label1.InvokeRequired)
{
Invoke(new DeviceInsertedCallback(DeviceInserted), new
object[] { Address });
}
else
{
label1.Text = "Login : " + Address;
}
}

Now my question is if it's possible not to have the code as above in my
form. Would it be possible to synchronize (or whatever) from within my
worker thread.

Thanks in advance,

Bart

Peter Duniho

unread,
Jun 24, 2008, 4:22:04 PM6/24/08
to
On Tue, 24 Jun 2008 12:59:44 -0700, <b> wrote:

> [...]


> Now my question is if it's possible not to have the code as above in my
> form. Would it be possible to synchronize (or whatever) from within my
> worker thread.

Yes, it is possible, and without even changing the API you've designed.
But IMHO it's better not to. Your form delegate method has more implicit
information and can more appropriately manage the decision as to whether
to call Invoke() or not. Unless your worker thread is specifically
designed to deal with GUI classes (the BackgroundWorker class would be an
example of this type of exception to the rule), I think it's better to
leave the invoking to the actual GUI code.

For what it's worth, you could simplify your delegate method though:

public void DeviceInserted(string Address)
{
Invoke((MethodInvoker)delegate { label1.Text = "Login: "
+ Address; });
}

You're not specific about why you'd prefer not to have code like that
which you posted, but it's possible you'd find the above preferable.

I personally dislike the MSDN-recommended technique of checking
InvokeRequired. In almost every example I've ever run into, the method is
used only when invoking is required. That along with my distaste for a
method that is basically doing two entirely different things (invoking
itself, or actually doing some work) leads me to the alternate
implementation I propose above.

Even if the method is sometimes used when invoking isn't required, there's
no harm in calling Invoke(). The invoked delegate will simply be called
directly.

Pete

Göran Andersson

unread,
Jun 24, 2008, 4:22:20 PM6/24/08
to

Only the GUI thread can update the controls, so you need to make the
code run in the GUI thread somehow.

Instead of checking if invoke is required, you can just make the
background thread make the invoke directly. You know that the invoke is
always required from the background thread.

An alternative to invoking a method, is to put the data in some
(synchronised or volatile) variable that both threads have access to,
and have a timer in the GUI that checks the variable for a value to put
in the label.

--
Göran Andersson
_____
http://www.guffa.com

b

unread,
Jun 24, 2008, 4:55:57 PM6/24/08
to
Hi Göran,

Thanks for your reply

>
> Only the GUI thread can update the controls, so you need to make the code
> run in the GUI thread somehow.
>
> Instead of checking if invoke is required, you can just make the
> background thread make the invoke directly. You know that the invoke is
> always required from the background thread.
>
> An alternative to invoking a method, is to put the data in some
> (synchronised or volatile) variable that both threads have access to, and
> have a timer in the GUI that checks the variable for a value to put in the
> label.
>

Could you elaborate on this because I am not sure what you mean here.

Thanks again,

Bart

Peter Duniho

unread,
Jun 24, 2008, 5:11:53 PM6/24/08
to
On Tue, 24 Jun 2008 13:54:19 -0700, <b> wrote:

> personally I don't like it when my worker thread has to know anything
> about the gui.......what if a textbox is used next time.....

I don't understand the question. My proposed change is still in your Form
subclass. If you want to change to a different control, just do that.
The worker thread doesn't need to know anything about the form at all,
just as in the code you posted it doesn't.

There's really no difference between the code I posted and the code you
posted, except mine is more concise. They both do exactly the same thing,
and have exactly the same amount of information or lack thereof with
respect to the classes involved.

>> You're not specific about why you'd prefer not to have code like that
>> which you posted, but it's possible you'd find the above preferable.
>

> I don't want to saddle up the user which uses my code with the
> responsibilty to handle it the way I wrote. That's why

I'm not convinced that's a suitable reason. If your class isn't
specifically like the BackgroundWorker -- that is, it's not specifically
designed to work with GUI classes but rather is more general purpose than
that -- then a) it's really not that inconvenient for the user of your
library to handle the invoking, and b) it's more appropriate for him to do
so anyway.

> Any ideas left ?

You can look at the target of the delegate passed to you, see if it
implements ISynchronizeInvoke, and call Invoke() on that interface if it
does.

But really, that's something I'd only do if you specifically intend your
class to be used with GUI targets. Most threaded classes are more general
purpose than that, and are better off leaving the cross-thread management
to the code that knows the most about the situation (i.e. the GUI class
itself).

Pete

DeveloperX

unread,
Jun 24, 2008, 5:39:27 PM6/24/08
to

Opera 9.5 seems to have broken google groups again (or vice versa) so
I'll have to be brief as I can only see two lines. Take a look at
SynchronizationContext. There are quite a few good articles about it.

Peter Duniho

unread,
Jun 24, 2008, 5:48:15 PM6/24/08
to
On Tue, 24 Jun 2008 14:39:27 -0700, DeveloperX
<ianatho...@googlemail.com> wrote:

> [...]


>> > An alternative to invoking a method, is to put the data in some
>> > (synchronised or volatile) variable that both threads have access to,
>> and
>> > have a timer in the GUI that checks the variable for a value to put
>> in the
>> > label.
>>
>> Could you elaborate on this because I am not sure what you mean here.
>

> Opera 9.5 seems to have broken google groups again (or vice versa) so
> I'll have to be brief as I can only see two lines. Take a look at
> SynchronizationContext. There are quite a few good articles about it.

While SynchronizationContext is in fact yet another way to approach the
situation, a) it's probably superfluous since he's already dealing with a
class that supports cross-thread invocations, and b) it's definitely not
what Göran was writing about.

As far as Göran's actual comment goes, he's talking about polling some
variable that contains the data of interest. When he writes "synchronized
or volatile", he's not talking about SynchronizationContext. He's just
talking about either using a synchronization technique (such as lock(),
the Monitor class, the Interlocked class, etc.), or simply marking a
variable as volatile (which would work fine for a string or other
reference, or any atomically-written value for that matter).

I personally don't condone polling, and especially not for a situation
like this where there are perfectly reasonable alternatives. But it's
certainly a viable alternative if the OP really wants to go that way.

But it still doesn't have anything to do with SynchronizationContext.

Pete

DeveloperX

unread,
Jun 24, 2008, 6:14:15 PM6/24/08
to
On 24 Jun, 22:48, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote:
> On Tue, 24 Jun 2008 14:39:27 -0700, DeveloperX  
>

I replied to the wrong post. Seriously I'm giving up with google
groups at this point.I can't see anything. My point was, and I'm not
proof reading this, syncctx can move much of the worry about running
something on the right thread out of the gui and somewhere more
sensible. I'm also with you on polling. It's not the way forward.
Dear Google, fix this. Dear Opera, fix this.

Peter Duniho

unread,
Jun 24, 2008, 9:20:14 PM6/24/08
to
On Tue, 24 Jun 2008 15:14:15 -0700, DeveloperX
<ianatho...@googlemail.com> wrote:

> I replied to the wrong post. Seriously I'm giving up with google

> groups at this point. [...]


> Dear Google, fix this. Dear Opera, fix this.

For what it's worth, Opera has a servicable, if not great, newsreader
built into its messaging features. In fact, that's what I'm using right
now. Rather than using the web UI on Google Groups, just hook into a real
NNTP server. Your ISP probably includes access to one, and if it doesn't,
my understanding is that there are several free-access ones out there.
For sure, _this_ newsgroup is available, since you can get at it and every
other "microsoft..." newsgroup via Microsoft's own NNTP server (off the
top of my head, I think it's called "msnews.microsoft.com", but I not
completely sure).

Pete

b

unread,
Jun 25, 2008, 12:17:44 PM6/25/08
to
> I don't understand the question. My proposed change is still in your Form
> subclass. If you want to change to a different control, just do that.
> The worker thread doesn't need to know anything about the form at all,
> just as in the code you posted it doesn't.
>
> There's really no difference between the code I posted and the code you
> posted, except mine is more concise. They both do exactly the same thing,
> and have exactly the same amount of information or lack thereof with
> respect to the classes involved.
>


Sorry was a little bit tired yesterday. I didn't read your code
well.....sorry for that

I think I will stick to your proposal.

Thanks again,

Bart

DeveloperX

unread,
Jun 25, 2008, 2:39:28 PM6/25/08
to
On 25 Jun, 02:20, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote:
> On Tue, 24 Jun 2008 15:14:15 -0700, DeveloperX  
>

Good grief, I've been using Opera for years and never knew! I mainly
use the web browser interface to get through work firewalls, but I'll
give this a go now I'm home :)

Thanks

Todd Carnes

unread,
Jun 26, 2008, 6:00:59 PM6/26/08
to

I use aioe.cjb.net as my newserver. It's free, carry's a LOT of groups,
and it just works.

Todd

0 new messages