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

Multithreading and updating the GUI

P: n/a
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

Jun 27 '08 #1
Share this Question
Share on Google+
12 Replies


P: n/a
On Tue, 24 Jun 2008 12:59:44 -0700, <bwrote:
[...]
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
Jun 27 '08 #2

P: n/a
b wrote:
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
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
Jun 27 '08 #3

P: n/a
Hi Peter,

Thanks for your quick answer
For what it's worth, you could simplify your delegate method though:

public void DeviceInserted(string Address)
{
Invoke((MethodInvoker)delegate { label1.Text = "Login: " +
Address; });
}
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.....

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

Any ideas left ?

Bart

Jun 27 '08 #4

P: n/a
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

Jun 27 '08 #5

P: n/a
On Tue, 24 Jun 2008 13:54:19 -0700, <bwrote:
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
Jun 27 '08 #6

P: n/a
On 24 Jun, 21:55, <bwrote:
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
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.
Jun 27 '08 #7

P: n/a
On Tue, 24 Jun 2008 14:39:27 -0700, DeveloperX
<ia************@googlemail.comwrote:
[...]
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
Jun 27 '08 #8

P: n/a
On 24 Jun, 22:48, "Peter Duniho" <NpOeStPe...@nnowslpianmk.comwrote:
On Tue, 24 Jun 2008 14:39:27 -0700, DeveloperX *

<ianathomeag...@googlemail.comwrote:
[...]
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
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.
Jun 27 '08 #9

P: n/a
On Tue, 24 Jun 2008 15:14:15 -0700, DeveloperX
<ia************@googlemail.comwrote:
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
Jun 27 '08 #10

P: n/a
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

Jun 27 '08 #11

P: n/a
On 25 Jun, 02:20, "Peter Duniho" <NpOeStPe...@nnowslpianmk.comwrote:
On Tue, 24 Jun 2008 15:14:15 -0700, DeveloperX *

<ianathomeag...@googlemail.comwrote:
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
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
Jun 27 '08 #12

P: n/a
Peter Duniho wrote:
On Tue, 24 Jun 2008 15:14:15 -0700, DeveloperX
<ia************@googlemail.comwrote:
>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
I use aioe.cjb.net as my newserver. It's free, carry's a LOT of groups,
and it just works.

Todd
Jun 27 '08 #13

This discussion thread is closed

Replies have been disabled for this discussion.