2.0 Threads, Join() and Invoke

M

Melina

Hi,

I just want to run several threads at the same time.
The code below just hang because - I guess - it can't access the
TextBox.Text method.
What is wrong with tis code ?!

Thanks.

Melina.

public class Report
{
public TextBox _log;
private List<RptTemplate> _listeTemplate;
private List<CIF> _listeCIF;

public Report(TextBox logTextBox, List<RptTemplate> listeTemplate,
List<CIF> listeCIF)
{
_log = logTextBox;
_listeTemplate = listeTemplate;
_listeCIF = listeCIF;
}

public void runProduction()
{

List<Thread> threads = new List<Thread>();

foreach (CIF ptf in _listeCIF)
{
Thread aThread = new Thread(delegate() { createPdf(ptf); });
aThread.Start();
threads.Add(aThread);
}

foreach (Thread thread in threads)
thread.Join();

threads.Clear();

}

private void createPdf(CIF ptf)
{

UpdateTextBox("Working on: CIF n°" + ptf.Racine + "\r\n");

foreach (RptTemplate rpt in _listeTemplate)
{
UpdateTextBox("\tWorking on: CIF n°" + ptf.Racine + " --> "
+ rpt.Name + "\r\n");
}

}

delegate void OutputUpdateDelegate(string data);
public void UpdateTextBox(string data)
{
if (_log.InvokeRequired)
_log.Invoke(new OutputUpdateDelegate(OutputUpdateCallback),
new object[] { data });
else
OutputUpdateCallback(data);
}

private void OutputUpdateCallback(string data)
{
_log.Text += data;
}

}
 
P

Peter Duniho

Melina said:
Hi,

I just want to run several threads at the same time.
The code below just hang because - I guess - it can't access the
TextBox.Text method.
What is wrong with tis code ?!

Since you didn't bother to post a concise-but-complete code example that
reliably reproduces the problem, it's not possible to say for sure.

But I'd bet that you are calling your runProduction() method from the
main GUI thread, thus blocking that thread from processing any window
messages, including those necessary to handle the Invoke() call.

It is very important to not block the main GUI thread. Don't do that.
Fix your code so that you don't need the runProduction() method to wait
for the threads to actually finish. It should start them and then
return right away.

If you have additional work to do after the processing has been
completed, you need to detect that situation in a different way. For
example, keep a count of the number of threads currently running. At
the end of each thread, decrement the count, and if the result is 0,
that thread can execute whatever end-of-processing code needs to happen
(which can happen either in that thread, or as a result of a call to
Invoke(), or both, as appropriate to your needs).

Pete
 
M

Melina

Hi,

Thank's Peter for answering.

That's right, i am calling runProduction() from the main GUI thread :

private void button1_Click(object sender, EventArgs e) {
Report aReport = new Report(textBox1, listeTemplate, listeCIF);
aReport.runProduction();
}

How should I modify the code to avoid the problem ?

I tried :

Report aReport = new Report(textBox1, listeTemplate, listeCIF);
Thread mainThread = new Thread(aReport.runProduction);
mainThread.Start();

But that doesn't change anything...

Thanks again,

Melina.



Peter Duniho wrote:

Melina wrote:Since you did not bother to post a concise-but-complete code
16-Feb-10

Melina wrote:

Since you did not bother to post a concise-but-complete code example that
reliably reproduces the problem, it is not possible to say for sure.

But I'd bet that you are calling your runProduction() method from the
main GUI thread, thus blocking that thread from processing any window
messages, including those necessary to handle the Invoke() call.

It is very important to not block the main GUI thread. Don't do that.
Fix your code so that you do not need the runProduction() method to wait
for the threads to actually finish. It should start them and then
return right away.

If you have additional work to do after the processing has been
completed, you need to detect that situation in a different way. For
example, keep a count of the number of threads currently running. At
the end of each thread, decrement the count, and if the result is 0,
that thread can execute whatever end-of-processing code needs to happen
(which can happen either in that thread, or as a result of a call to
Invoke(), or both, as appropriate to your needs).

Pete

Previous Posts In This Thread:


Submitted via EggHeadCafe - Software Developer Portal of Choice
Adding WCF Service References
http://www.eggheadcafe.com/tutorial...9-dfa51a9fab8e/adding-wcf-service-refere.aspx
 
P

Peter Duniho

Melina said:
[...]
That's right, i am calling runProduction() from the main GUI thread :

private void button1_Click(object sender, EventArgs e) {
Report aReport = new Report(textBox1, listeTemplate, listeCIF);
aReport.runProduction();
}

Given the above, why do you want the runProduction() method to wait at
all? It's not like you're doing anything useful once the threads are
all done.
How should I modify the code to avoid the problem ?

I tried :

Report aReport = new Report(textBox1, listeTemplate, listeCIF);
Thread mainThread = new Thread(aReport.runProduction);
mainThread.Start();

But that doesn't change anything...

Well, it should.

The other thing you could do is just change the runProduction() method
so that it doesn't do useless stuff:

public void runProduction()
{
foreach (CIF ptf in _listeCIF)
{
new Thread(delegate() { createPdf(ptf); })
.Start();
}
}

Either approach should fix any blocking of the main GUI thread.

If neither of those help, you really need to post a concise-but-complete
code example that reliably demonstrates the problem.

Pete
 

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

Top