472,956 Members | 2,631 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,956 software developers and data experts.

Stop a function

I made a program that generate random numbers and put it in a listbox when
the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...
Nov 16 '05 #1
26 4621
There are a few ways, but you could use IAsyncResult for instance, and use a
while loop. the while could read in a bool. When the user hits the button,
set the bool to false. By using another thread, you won't freeze up the UI.
http://www.knowdotnet.com/articles/delegates.html
"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox when
the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...

Nov 16 '05 #2
> I made a program that generate random numbers and put it in a listbox when
the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???

You need to run that method in a separate Thread. If you press the button,
set a flag which you test in the method and return in this case.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #3
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a
Stop button that set a flag to false, before the next number is generated yo
check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can pause
the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main thread
using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop
me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox when
the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...

Nov 16 '05 #4
Scenario #1 is preferable to spawning a thread, which would be difficult to
manage, test, debug, etc.

Brad Williams
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a
Stop button that set a flag to false, before the next number is generated yo check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can pause
the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main thread using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop
me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox when the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...


Nov 16 '05 #5
Hi,

It's as long as the operation to be performed is not lengthy, if it's the
UI will hang until the call to DoEvents() .
Cheers,

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

"Brad Williams" <sp**@spam.com> wrote in message
news:c7**********@news01.intel.com...
Scenario #1 is preferable to spawning a thread, which would be difficult to manage, test, debug, etc.

Brad Williams
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote in message news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a Stop button that set a flag to false, before the next number is generated
yo
check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can

pause the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main

thread
using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox

when the user click go.
The problem is: how can i made a button stop, to stop the method that is running???
[]s...



Nov 16 '05 #6
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> a
écrit dans le message de news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a
Stop button that set a flag to false, before the next number is generated yo check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can pause
the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main thread using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop
me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox when the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...



Hi.

The use of DoEvent is a very risky practice. Indeed, any event can occur
during the call of doevent. It might change some input you are dealing with
in your generateRandom method.
You must be very cautious of not encounter some incoherences.
Althought it may look a little bit more complex, you should definitely use a
worker thread. It is much easier to control.

Fred
Nov 16 '05 #7
"Iceman" <fr************************@neuf.fr> wrote in message
news:c7**********@aphrodite.grec.isp.9tel.net...
The use of DoEvent is a very risky practice.


This is exactly how we handled this in Windows 3.1, and the code was ugly
but actually much less error prone than trying to herd threads.
Multithreaded programming is harder than most people realize, unfortunately.

Brad Williams
Nov 16 '05 #8
could you send the code of scenario 2 to my e-mail:
dr*******@terra.com.br

bye...
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a
Stop button that set a flag to false, before the next number is generated yo check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can pause
the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main thread using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop
me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox when the user click go.
The problem is: how can i made a button stop, to stop the method that is
running???
[]s...


Nov 16 '05 #9
The UI is hanging, the scenario 1 not work...

"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:eM**************@TK2MSFTNGP10.phx.gbl...
Hi,

It's as long as the operation to be performed is not lengthy, if it's the
UI will hang until the call to DoEvents() .
Cheers,

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

"Brad Williams" <sp**@spam.com> wrote in message
news:c7**********@news01.intel.com...
Scenario #1 is preferable to spawning a thread, which would be difficult to
manage, test, debug, etc.

Brad Williams
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>

wrote
in message news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a
Stop button that set a flag to false, before the next number is generated
yo
check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can pause the thread execution, remember that if you use this approach you have
to make sure that the call to update the interface be called in the main thread
using Control.Invoke

Pd: I will not post code for this as its a little more complex, just

drop me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
> I made a program that generate random numbers and put it in a
listbox when
> the user click go.
> The problem is: how can i made a button stop, to stop the method

that is > running???
>
>
> []s...
>
>



Nov 16 '05 #10
Brad Williams <sp**@spam.com> wrote:
The use of DoEvent is a very risky practice.


This is exactly how we handled this in Windows 3.1, and the code was ugly
but actually much less error prone than trying to herd threads.
Multithreaded programming is harder than most people realize, unfortunately.


Sure - but calling DoEvents is also riskier than most people realise, I
believe.

Sooner or later, pretty much every serious .NET programmer is going to
*have* to start to understand threading. Why not encourage people to
grab the bull by the horns and learn how to do it properly now? I don't
think encouraging them to use what is essentially a nasty workaround
hack is a good idea.

Must get round to finishing my article on multi-threading soon...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #11
Hi Ricardo,

I posted it here for it to get archived.
A have a suggestiong though, maybe is better for you to use a textbox to
indicate how many numbers the user want, if you depend of the user clicking
a Stop button it will be dependant of the speed of the machine.

PD:
this is only togive you an idea of how to do it, it will runs fine
although.

Cheers,
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
public delegate void InsertNumberHandler( int numberToInsert);

InsertNumberHandler onnewnumber;
Thread workingThread;
bool keepgoing = true;

Random random = new Random( DateTime.Now.Second );

public Form1()
{
onnewnumber = new InsertNumberHandler( NewNumber);
workingThread = new Thread( new ThreadStart( NumberGenerator));
}

void NewNumber( int i )
{
this.comboBox1.Items.Add( i);
}
void NumberGenerator()
{
while( keepgoing)
{
int i = random.Next();
this.comboBox1.Invoke ( onnewnumber, new object[] { i} );
Thread.Sleep(1000);
}

}
private void StartBTN_Click(object sender, System.EventArgs e)
{
if ( workingThread.ThreadState == ThreadState.Unstarted )
workingThread.Start();
else
workingThread.Resume();
}

private void StopBTN_Click(object sender, System.EventArgs e)
{
workingThread.Suspend();
}
// Terminate the working thread
private void Form1_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
keepgoing = false;
}
"Ricardo" <dr*******@terra.com.br> wrote in message
news:uY**************@TK2MSFTNGP12.phx.gbl...
could you send the code of scenario 2 to my e-mail:
dr*******@terra.com.br

bye...
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote in message news:u7**************@tk2msftngp13.phx.gbl...
Hi Ricardo,

There are a few ways of doing it , it all depend of how/where you run the
random generator, I will show you two escenarios
1- gen. runs on the same thread.

while you are generating numbers , between number generation you call
Application.DoEvents() this process the events queries, you can then use a Stop button that set a flag to false, before the next number is generated
yo
check for this flag, like this:

bool generate = true;
void generaterandom( object sender, EventArgs e )
{
while ( generate)
{
// generate it and update the UI
Application.DoEvents();
}

}
void Stop_OnClick( object sender, EventArgs e )
{
generate = false;
}

2- run the generator on another thread and then the Stop button can

pause the thread execution, remember that if you use this approach you have to
make sure that the call to update the interface be called in the main

thread
using Control.Invoke

Pd: I will not post code for this as its a little more complex, just drop me a note if you need it

HTH,

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

"Ricardo" <dr*******@terra.com.br> wrote in message
news:O9**************@TK2MSFTNGP12.phx.gbl...
I made a program that generate random numbers and put it in a listbox

when the user click go.
The problem is: how can i made a button stop, to stop the method that is running???
[]s...



Nov 16 '05 #12
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
I posted it here for it to get archived.


Unfortunately it'll be archived including its bug then :(

Your code uses a non-volatile boolean variable (keepgoing), and updates
and reads it without any locking or memory barriers being involved.
It's therefore not guaranteed that the reading thread will ever see the
value changed in another thread.

In practice this won't actually be a problem, as the JIT *isn't* going
to cache the value, but it theoretically could - the code is
theoretically broken.

The simple way to fix it is to have a reference which is locked every
time you touch the shared data (the boolean). The easiest way of doing
that is to use properties to access the data and put locks in the
property:

bool keepGoing;
object keepGoingLock = new object();

public bool KeepGoing
{
get
{
lock (keepGoingLock)
{
return keepGoing;
}
}
set
{
lock (keepGoingLock)
{
keepGoing = value;
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #13
Hi jon,

You are as always right :)

It should be locked

Thanks for point it.

Cheers,

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

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
I posted it here for it to get archived.


Unfortunately it'll be archived including its bug then :(

Your code uses a non-volatile boolean variable (keepgoing), and updates
and reads it without any locking or memory barriers being involved.
It's therefore not guaranteed that the reading thread will ever see the
value changed in another thread.

In practice this won't actually be a problem, as the JIT *isn't* going
to cache the value, but it theoretically could - the code is
theoretically broken.

The simple way to fix it is to have a reference which is locked every
time you touch the shared data (the boolean). The easiest way of doing
that is to use properties to access the data and put locks in the
property:

bool keepGoing;
object keepGoingLock = new object();

public bool KeepGoing
{
get
{
lock (keepGoingLock)
{
return keepGoing;
}
}
set
{
lock (keepGoingLock)
{
keepGoing = value;
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #14
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.

And there's a textbox wich the number the user want...
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:ep**************@TK2MSFTNGP12.phx.gbl...
Hi jon,

You are as always right :)

It should be locked

Thanks for point it.

Cheers,

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

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<"Ignacio Machin \( .NET/ C# MVP \)" <ignacio.machin AT
dot.state.fl.us>> wrote:
I posted it here for it to get archived.


Unfortunately it'll be archived including its bug then :(

Your code uses a non-volatile boolean variable (keepgoing), and updates
and reads it without any locking or memory barriers being involved.
It's therefore not guaranteed that the reading thread will ever see the
value changed in another thread.

In practice this won't actually be a problem, as the JIT *isn't* going
to cache the value, but it theoretically could - the code is
theoretically broken.

The simple way to fix it is to have a reference which is locked every
time you touch the shared data (the boolean). The easiest way of doing
that is to use properties to access the data and put locks in the
property:

bool keepGoing;
object keepGoingLock = new object();

public bool KeepGoing
{
get
{
lock (keepGoingLock)
{
return keepGoing;
}
}
set
{
lock (keepGoingLock)
{
keepGoing = value;
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Nov 16 '05 #15
> Sure - but calling DoEvents is also riskier than most people realise, I
believe.

Sooner or later, pretty much every serious .NET programmer is going to
*have* to start to understand threading. Why not encourage people to
grab the bull by the horns and learn how to do it properly now? I don't
think encouraging them to use what is essentially a nasty workaround
hack is a good idea.

So what exactly is risky with DoEvents()? The worst thing I can imagine is
that the UI has slow response times, thats all.
With threads you have much more problems and things to care about.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #16
> Your code uses a non-volatile boolean variable (keepgoing), and updates
and reads it without any locking or memory barriers being involved.
It's therefore not guaranteed that the reading thread will ever see the
value changed in another thread.

In practice this won't actually be a problem, as the JIT *isn't* going
to cache the value, but it theoretically could - the code is
theoretically broken.

The simple way to fix it is to have a reference which is locked every
time you touch the shared data (the boolean). The easiest way of doing
that is to use properties to access the data and put locks in the
property:

bool keepGoing;
object keepGoingLock = new object();

public bool KeepGoing
{
get
{
lock (keepGoingLock)
{
return keepGoing;
}
}
set
{
lock (keepGoingLock)
{
keepGoing = value;
}
}
}

Nothing stops the Jit from inlining this property and nobody guarantees you
that keepGoing is reloaded from memory each time you call it, at least in
theory.
I also do not understand what locking in this case is good for since you
have only one operation in the method body.

The simplest and safest solution is a volatile variable.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #17
Ricardo <dr*******@terra.com.br> wrote:
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.


So don't call DoEvents - do your processing in a different thread.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #18
cody <pl*************************@gmx.de> wrote:
So what exactly is risky with DoEvents()? The worst thing I can imagine is
that the UI has slow response times, thats all.
Your stack gets deeper and deeper the more things which go on within
your DoEvents, possibly leading to a StackOverflow which is solely due
to simulating multiple threads within a single thread.

If you make *any* blocking calls, you are tying up your UI for a
potentially *very* long time - not just slow response times, but a
completely *unresponsive* UI.

You still have to work out which bits of code must execute in a sort of
"transactional" way without calling DoEvents again, in case the other
events will modify data you're relying on not changing.

See "On COM, pumping and the CLR" in
http://mikedimmick.blogspot.com/2004...k_archive.html
for some another example.

Fundamentally the usual problem is wanting to do more than one thing at
a time - and that's precisely what threads are designed to do.
With threads you have much more problems and things to care about.


Sure - but there are good solutions to all of them. As I said, sooner
or later, all serious .NET developers are going to understand threading
- so why not learn the "proper" way of doing things once, rather than
first learning the hacky not-suitable-for-all-situations way (along
with the rules as to what makes a situation suitable or not) and then
having to learn threading anyway?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #19
cody <pl*************************@gmx.de> wrote:
Nothing stops the Jit from inlining this property
Immaterial.
and nobody guarantees you
that keepGoing is reloaded from memory each time you call it, at least in
theory.
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.
I also do not understand what locking in this case is good for since you
have only one operation in the method body.

The simplest and safest solution is a volatile variable.


Locks are just as safe, and given that you'll need to use them at
*some* point, it makes sense (to me) to only learn one method of
thread-safety, rather than working out when to use a volatile and when
to use a lock.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #20
Hi Ricardo,
"Ricardo" <dr*******@terra.com.br> wrote in message
news:ee**************@TK2MSFTNGP09.phx.gbl...
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,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Nov 16 '05 #21
> I don't
think encouraging them to use what is essentially a nasty workaround
hack is a good idea.

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().

cody wrote: 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
Nov 16 '05 #22
Brad Williams <sp**@spam.com> wrote:
I don't
think encouraging them to use what is essentially a nasty workaround
hack is a good idea.

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.
cody wrote:
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.


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?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #23
> > and nobody guarantees you
that keepGoing is reloaded from memory each time you call it, at least in theory.


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

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #24
cody <pl*************************@gmx.de> wrote:
Those volatile reads and writes then assure acquire/release semantics.


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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #25
Hi Jon, I normally don't even see your posts during the day, but at home my
news server picks them up...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Brad Williams <sp**@spam.com> wrote:
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).


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
Nov 16 '05 #26
Brad Williams <sp**@wcsoft.com> wrote:
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.


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

<snip>
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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: engsol | last post by:
I'm using Python to parse a bunch of s/w test files and make csv files for later report generation by MS ACCESS....(my boss loves the quick turn-around compared to C). Each log file may contain one...
8
by: Eric Osman | last post by:
My javascript program has reason to want to stop. For example, function A has 5 lines, the second of which calls function B, which has 5 lines, the first of which calls function C. But...
2
by: Adrian MacNair | last post by:
Hi I need some help if anyone can understand my crap javascript. The problem is that after the slideshow ends (reaches the end of array) it should stop, but the timeout doesn't clear and I can see...
4
by: David | last post by:
Hi everyone, I am trying to stop an image preload sequence by the click of a mouse but have been unsuccessful trying several methods. Imagine this simple script below that loads 50 images to...
7
by: jab3 | last post by:
Hello. I'm wondering if someone can answer something I'm sure has been answered a thousand times before. I am apparently just too dumb to find the answer. :) I've found information about the...
2
by: eSolTec, Inc. 501(c)(3) | last post by:
Thank you in advance for any and all assistance. Is there a way to start, pause and resume a recurrsive search exactly where you left off, say in the registry programmatically? -- Michael Bragg,...
1
by: Simone | last post by:
Hello In visual studio when I am debugging my ASP. net code if I hit "stop" the procedure I am in will still finish itself and doesn't stop where I expect it to stop. I remember in VB when...
4
by: ravindarjobs | last post by:
hi...... i am using ms access 2003,vb6 i have a form. in that i have 2 buttons 1. start search 2 stop search when i click the "start search" button the fucntion SearchSystem() is called,...
8
praclarush
by: praclarush | last post by:
Ok, I'm new to JavaScript and I'm taking a class for it the assignment in it I'm supposed to create edit a pre-made page to display a marquee that automatically scrolls for the user, as well as give...
4
by: Rajneesh Chellapilla | last post by:
I wrote this program. Its kinda of strange when I make a reset function reset(){c=0} its doest reset the setTimeout. However if I directly pass c=0 to the onclick button it does reset the timer. What...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.