Stop a function

  • Thread starter Thread starter cody
  • Start date Start date
Hi Ricardo,


Ricardo said:
i made a stop button that turn the bool to false, and made calls to doevents
in some critical parts of the method, the problem is that the UI hang and i
can't press the button.

You don't need to call to DoEvents if you are using a working thread as my
example does, I tested it and I don;t see the UI hanging.
And there's a textbox wich the number the user want...


Then why you need a stop button?


Cheers,
 
I don't
You can call it names, but if and when it gets the job done, it's a good
thing. The classic gotcha with ad hoc message pumping is you have to watch
out for re-entrency -- eg, if you create a message pump within a button
event, first disable the button so you don't get the same event again while
you're processing the first one. Of course that may be something you want
to control for when spawning threads, too, so it's not a unique problem to
DoEvents().
With threads you have much more problems and things to care about.

Once there's more than one thread touching your data, the complexity at
run-time increases immensely. It can be hard to impossible to test (in unit
tests or later) for all the potential bugs in multithreaded code (on our
dual procs, right?) -- and oftentimes it will "work" in a few test runs and
so you think you've got it licked, but you don't. And if you are lucky
enough to realize there's a problem, debugging is very tricky. ... Okay, I
shouldn't say "you" because I'm speaking from experience and I'm the one
whose had all these headaches in the past, but I don't think others are
immune. ;)

Brad Williams
 
Brad Williams said:
You can call it names, but if and when it gets the job done, it's a good
thing.

That sounds like the recipe for bad code - and unsafe code (from a
thread safety point of view). There are any number of bits of code
which may happen to work on your development machine, but which are
very *far* from good things - because they may well *not* work on
machines with more processors, or a different default encoding, or any
number of other things.
The classic gotcha with ad hoc message pumping is you have to watch
out for re-entrency -- eg, if you create a message pump within a button
event, first disable the button so you don't get the same event again while
you're processing the first one. Of course that may be something you want
to control for when spawning threads, too, so it's not a unique problem to
DoEvents().

Well, there's more to re-entrancy than that though, isn't there? The
link I posted before gives some idea of the kind of nastiness you can
run into.
Once there's more than one thread touching your data, the complexity at
run-time increases immensely.

Absolutely. I'm certainly not pretending that multi-threading is
simple. I just find it easier to work with than the spectre of re-
entrancy. As Chris Brumme says in his log:

<quote>
Avalon also has made a conscious design choice to favor deadlocks over
reentrancy. In my opinion, this is an excellent goal. Deadlocks are
easily debugged. Reentrancy is almost impossible to debug. Instead,
it results in odd inconsistencies that manifest over time.
</quote>

While I wouldn't say that deadlocks are *easily* debugged, I'd say
they're not *too* bad - and they're *relatively* easy to avoid, if
you're careful about documenting what locks happen when.
It can be hard to impossible to test (in unit
tests or later) for all the potential bugs in multithreaded code (on our
dual procs, right?) -- and oftentimes it will "work" in a few test runs and
so you think you've got it licked, but you don't.

Yup - and the same is true for DoEvents, isn't it?
And if you are lucky enough to realize there's a problem, debugging
is very tricky. ... Okay, I shouldn't say "you" because I'm speaking
from experience and I'm the one whose had all these headaches in the
past, but I don't think others are immune. ;)

Absolutely not - and threading really *is* a nightmare. DoEvents is
also a nightmare - it's just one which sort of *pretends* to be simple.
It has a different set of problems to work around.

Now, as I've said before, sooner or later you will *need* to use
threads (do anything which might block in DoEvents and you've got an
unresponsive UI), why not become really proficient in one area rather
than knowing a little about two different areas?
 
and nobody guarantees you
Yes, the spec guarantees it. From section 12.6.5 of the ECMA CLR spec,
partition 1:

<quote>
Acquiring a lock (System.Threading.Monitor.Enter or entering a
synchronized method) shall implicitly perform a volatile read
operation, and releasing a lock (System.Threading.Monitor.Exit or
leaving a synchronized method) shall implicitly perform a volatile
write operation.
</quote>

Those volatile reads and writes then assure acquire/release semantics.

A volatile read/write on what? *All* local variables in the code block???
 
cody said:
A volatile read/write on what? *All* local variables in the code block???

It doesn't matter. A single volatile read is all that's required for
the appropriate memory barrier.

From the spec:

<quote>
A volatile read has acquire semantics meaning that the read is
guaranteed to occur prior to any references to memory that occur after
the read instruction in the CIL instruction sequence. A volatile write
has release semantics meaning that the write is guaranteed to happen
after any memory references prior to the write instruction in the CIL
instruction sequence.
</quote>

There's nothing in there which says anything about which variable is
read etc.
 
Hi Jon, I normally don't even see your posts during the day, but at home my
news server picks them up...

Jon Skeet said:
That sounds like the recipe for bad code - and unsafe code (from a
thread safety point of view).

Well, you're reading too much into it then. I'm saying there are situations
where DoEvents() fits the bill, so it shouldn't be written off as a hack.
Well, there's more to re-entrancy than that though, isn't there? The
link I posted before gives some idea of the kind of nastiness you can
run into.

Okay, but if the code is written to not be re-entrant, then there's no
nastiness.
While I wouldn't say that deadlocks are *easily* debugged, I'd say
they're not *too* bad - and they're *relatively* easy to avoid, if
you're careful about documenting what locks happen when.

Relative to what? Multithreaded programming is some of the hardest
programming to get right (and no, that's not true of ad hoc message pumps).
Ignacio seems like a smart guy ... and you found a bug in his multithreading
code!

DoEvents() has far less application, but it's about an order of magnitude
easier to use safely in those few situations where it applies. As I said,
I've seen more and worse messes caused by threads than by ad hoc message
pumps. This is partly because threading code is surprisingly difficult to
write. So the lesson is both: only spawn threads when you really need to,
and know what you're doing when you do it.

Cheers,
Brad Williams
 
Brad Williams said:
Well, you're reading too much into it then. I'm saying there are situations
where DoEvents() fits the bill, so it shouldn't be written off as a hack.

I think we'll have to agree to disagree on this.

DoEvents() has far less application, but it's about an order of magnitude
easier to use safely in those few situations where it applies. As I said,
I've seen more and worse messes caused by threads than by ad hoc message
pumps. This is partly because threading code is surprisingly difficult to
write. So the lesson is both: only spawn threads when you really need to,
and know what you're doing when you do it.

And I'd say the lesson is exactly the same with DoEvents - you
definitely still need to know what you're doing in order to either
anticipate re-entrancy or prevent it from occurring in the first place.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top