willing to share them (and once again, I appeared to have caused you to get a irratated somehow). Please excuse me for that....I am not that experienced of a programmer, but don't fault me for trying to learn.
I have quoted the last part of your post first, because it demonstrates
a misunderstanding. I don't know why you think I'm irritated; I'm not.
However, the fact is that you haven't presented your question in a way
that would best serve your interests.
You need to remember: every answer provided here is strictly on a
volunteer basis. The more work you make someone else do in order to try
to understand and answer your question, the less likely it is your
question will be answered.
Beyond that, there are simply some minimum requirements that are
necessary in order to receive a correct or useful answer, and your
original post doesn't really meet those requirements. I have tried to
help you understand what those requirements are. You seem to think that
someone trying to help you means that they are irritated with you. How
you come to that conclusion is a mystery to me, but suffice to say it's
the wrong conclusion.
Now, for the rest of your post...
Peter, please excuse the rest of us less experienced programmers from
attempting to ask professionals such as yourself a question the best way I
can. I am trying to solve a problem to better myself at programming. I use
MSDN groups because I usually have courteous responses (without Uppercase
emphasis on words) from the many good programmers here.
I have been nothing but courteous. Any perception on your part
otherwise is due to your misunderstanding, not lack of courtesy.
I have not provided
specific examples from the program I am writing because it would not compile
(and run) on anyone's computer without having internal parts of the
application (i.e. network locations, etc.).
That is the point of asking for a concise-but-complete sample. Of
course you should not post your whole program, for the reasons you state
and others.
But the fact is, most of the stuff in your program has absolutely
nothing to do with the problem you're asking about. Even the specific
calculation is not meaningful; you could (and should) replace that code
in a sample with some placeholder, like a call to Thread.Sleep()
specifying a time that is similar to that your calculations normally take.
Likewise the rest of the logic that is relevant to your program. Create
a new sample program that incorporates all of the relevant logic, and
nothing else.
Yes, this is more work for you. However, a) you will learn a great deal
in making such an example, and in fact oftentimes a person will discover
the answer to their own question by removing all the clutter from the
basic problem, and b) it is futile for us to try to figure out what your
program does without any code to read. Only in the simplest cases does
it suffice to describe in English the operation of the code. This is
definitely not a simple case.
I tried giving an example to the best of my ability. Please don't fault me
for using Main(), I was shortening the form names load event.
I must fault you, because using the name of a method that has a very
specific meaning in the context of a .NET/C# program is EXTREMELY
misleading. If you will not provide an actual code sample, you must at
least ensure that you only describe your code in unambiguous terms, and
definitely not using terms that already have very specific meaning in
this context but which are not the meaning you intend.
I appreciate the clarification, but the solution is to not use the wrong
terminology in the first place. It's a valid criticism of your post,
and rather than being defensive about it, you should simply accept the
criticism, comprehend why it's valid, and move on (avoiding the
repetition of the mistake in the future, of course).
Again, the
root issues I am trying to resolve is that I want to run a series of
computations. At the same time these computations are running, I want a
listbox that is constantly updating to reflect the activity of each set of
computations without the main form from blocking UI controls and rendering.
That describes a very basic technique, one that has been explained many
times in this newsgroup. The basic idea is to create the thread and use
Invoke() to interact with the Listbox instance. You'll find many
examples and discussions on the technique if you search the newsgroup
using Google Groups.
However, using that technique you would not use the Join() method. As
has been stated several times already, Join() defeats the entire purpose
of putting your computations in a separate thread. Don't use Join().
So I figured if I used a second thread to process the computations the main
form (and listbox) could be updated without issue (i.e. the form would not be
unresponsive and I could watch listbox activities in real time). I basically
don't have an issue with executing the first computation, but I do have an
issue where I would like a second computation to run only after the first
completes (and I don't want the worker thread to execute the second
computation).
This is the first time I have seen you say anything about wanting to
perform a second computation after the first completes. This is a key
piece of information regarding your question that you've left out up to
this point.
Now, with that information, we can provide a more useful answer to you:
You still do not need to call Join(). It's not at all clear to me the
point of your objection to continuing in the worker thread after the
first computation, to go on and do the second. However, assuming that's
a valid requirement, you have at least two options:
1) Notify the form via some mechanism that the first computation
thread has completed, at which point the form will start the second
computation thread. The easiest way to do this would be to define a
method on the form that will do this.
You can either use Invoke() to call the method (this would be required
if the code starting the second computation thread needs access to
something in the base Form class), or you could just call the method
directly. In the latter case, this is not much different from your
second option, which is...
2) In the first computation thread, simply start the second
computation thread before exiting.
Either technique will work fine, and neither requires the use of the
Join() method.
Personally, I prefer using the BackgroundWorker class for stuff like
this. In the class you add handlers for the DoWork and
RunWorkerCompleted events, where the DoWork handler performs your
computation, and the RunWorkerCompleted handler does whatever you want
done upon completion of the work (including starting a new computation
if desired). The nice thing about BackgroundWorker is that the
RunWorkerCompleted event is automatically executed on the same thread
that created the BackgroundWorker, so if you have some Form-dependent
stuff you don't need to bother calling Invoke(). You'll already be
handling the event on the correct thread.
I was hoping that someone would have ideas and would be
willing to share them (and once again, I appeared to have caused you to get a
irratated somehow). Please excuse me for that....I am not that experienced
of a programmer, but don't fault me for trying to learn.
No one is faulting you for trying to learn. But if you are actually
interested in learning, you also need to be interested in how to best
present your questions. It's very difficult to answer a question that
doesn't accurately or completely describe what the questioner really
wants. Instead, it creates confusion and frustration as the question
that was actually asked is answered, but the questioner comes back and
says "but you didn't answer my question".
What the questioner means is "you didn't answer the question I actually
have", even as it's true that the answerer _did_ in fact answer the
question that was asked.
You need to get past any defensiveness with respect to constructive
criticism, and just understand that these replies are intended to help.
You may be sitting there thinking "well, why don't you just answer my
question instead of hassling me", but the fact is that sometimes the
best way to solve a person's problem is to first work on the techniques
necessary in order to get the person to state the problem in a way that
allows it to be answered.
Basically, no one can answer your question unless they understand it,
and so when we don't understand the question, our first step is to help
you learn how to better state your question. Otherwise, we're just
answering some random question that may or may not have anything to do
with your real question.
Pete