.NET Threading Question

A

Arun Kumar

What is wrong with this code. All i am trying to test is 3 progressbar and
one button. On buttonclick i create 3 threads and each thread calls a method
which in turn updates the progressbar and it works. I would to know if this
can be used.
Thanks
private void button1_Click(object sender, System.EventArgs e)

{

ThreadStart job = new ThreadStart(onemethod);

Thread thread = new Thread(job);

thread.Start();

ThreadStart job1 = new ThreadStart(secondmethod);

Thread thread1 = new Thread(job1);

thread1.Start();

ThreadStart job2 = new ThreadStart(thirdmethod);

Thread thread2 = new Thread(job2);

thread2.Start();



}

public void onemethod()

{

for (int i=0;i<100;i++)

{

progressBar1.Value = i;

Thread.Sleep(100);

}

}

public void secondmethod()

{

for (int i=0;i<100;i++)

{

progressBar2.Value = i;

Thread.Sleep(100);

}

}

public void thirdmethod()

{

for (int i=0;i<100;i++)

{

progressBar3.Value = i;

Thread.Sleep(100);

}

}
 
D

DotNet Coder

Hi Arun,

The code should work fine, although it violates best practices by
interacting directly with the UI from threads other than the main
thread. Other than that though, it *looks* like it should run just fine.

~d
 
D

DotNet Coder

Completely wrong... if you use threads and use it carefully, it will
still be a problem. As that article states, "Never invoke any method or
property on a control created on another thread other than Invoke,
BeginInvoke, EndInvoke or CreateGraphics, and InvokeRequired.".

This is not just a golden rule, it is a fact of winforms programming.
When you start messing with objects created in other threads, you start
running into all sorts of problems, like race conditions, deadlocks, etc.

Also, as the author stated, you may get away with it for awhile, but
eventually, your application will start displaying some pretty strange
behaviors and debugging could become a horrible process, especially if
it is threading errors that are killing the app.

HTH,
~d
 
W

Willy Denoyette [MVP]

Arun Kumar said:
DotNet Coder,

I agree, its not the best practices but my point is, if you use threads
and use it carefully it shouldn't be a problem.
Check this link
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

let me know you comments.

Arun

There is nothing "carefully" with this, it may work in this simple sample
and it may work a million times but sooner or later it will break, it's
simply wrong to touch the UI element (a window handle) from a thread other
than the thread that owns the handle.

Willy.
 
J

Jon Skeet [C# MVP]

Arun Kumar said:
I agree, its not the best practices but my point is, if you use threads and
use it carefully it shouldn't be a problem.

Not true.

Which part of:

<quote>
Never invoke any method or property on a control created on another
thread other than Invoke, BeginInvoke, EndInvoke or CreateGraphics, and
InvokeRequired.
</quote>

gives you the impression that it shouldn't be a problem?
 
A

Arun Kumar

Alright,
Let me go back a step and tell you what i did in Win32 and I know it may not
be true in "WinForms"(As Microsoft keeps changing things)
I am a Delphi Developer, in Delphi, I got a Mainform with a statusbar and a
Thread which creates database.
I use Synchronize() to update the main form which i believe is correct.

I want to do the same in .Net and after playing around with things and
reading the article. (Correct me if i m wrong here)
1. Creating the Thread from Mainform
2. If the Thread calls a method which updates the mainform, is this wrong?

I dont want to write complex code just update the mainform.
Very simple
Mainform -> Creates Thread -> does some background database stuff, while
doing that it should update the mainform telling the user hey I am still
working on it wait till i complete it and also give them an indication where
its at.
This is what i am looking for and started playing with Threads. If its were
to be Delphi its a "piece of Cake" and I can do it with few lines.
But, I thought .Net is going to make coding lot easier I guess not.
<Article>" class itself, setting it in one thread, retrieving and processing
it in the other (updating the display in the UI thread, for example).
"<Article> Create a Thread to do stuff and create another Thread to update
UI what is going on here???

Anyway there is no point in hitting the wall

Arun
 
D

DotNet Coder

Hey Jon? Didn't you write an article on this very subject? I seem to
remember you mentioning an article sometime last year.

~d
 
A

Arun Kumar

Willy Denoyette said:
There is nothing "carefully" with this, it may work in this simple sample
and it may work a million times but sooner or later it will break, it's
simply wrong to touch the UI element (a window handle) from a thread other
than the thread that owns the handle.

Willy.
Thanks for your response.

Yes. I know that. there is nothing called "carefully". I have worked on
Threads alot in Win32 and I know what will have happen.
" simply wrong to touch the UI element (a window handle) from a thread
other than the thread that owns the handle."
True. its a sample, yes I am trying out things what i can and what i cannot
do in .Net and what are the limitations and I strong believe there is
nothing wrong in doing that and putting my words out here and get the best
out it.

Arun
 
J

Jon Skeet [C# MVP]

Arun Kumar said:
Let me go back a step and tell you what i did in Win32 and I know it may not
be true in "WinForms"(As Microsoft keeps changing things)
I am a Delphi Developer, in Delphi, I got a Mainform with a statusbar and a
Thread which creates database.
I use Synchronize() to update the main form which i believe is correct.

I'm afraid I don't know what Synchronize() does in Delphi. The "don't
change the UI from a non-UI thread" is a general Win32 rule though.
I want to do the same in .Net and after playing around with things and
reading the article. (Correct me if i m wrong here)
1. Creating the Thread from Mainform
2. If the Thread calls a method which updates the mainform, is this wrong?
Yes.

I dont want to write complex code just update the mainform.
Very simple
Mainform -> Creates Thread -> does some background database stuff, while
doing that it should update the mainform telling the user hey I am still
working on it wait till i complete it and also give them an indication where
its at.

Sure - so use Invoke or BeginInvoke, and you should be fine. There's a
pretty full example in the article.
This is what i am looking for and started playing with Threads. If its were
to be Delphi its a "piece of Cake" and I can do it with few lines.
But, I thought .Net is going to make coding lot easier I guess not.
<Article>" class itself, setting it in one thread, retrieving and processing
it in the other (updating the display in the UI thread, for example).
"<Article> Create a Thread to do stuff and create another Thread to update
UI what is going on here???

You don't create another thread to update the UI - you tell the
existing UI thread to update the UI.
Anyway there is no point in hitting the wall

There's every point in learning how to do it properly though. I suggest
you read the article again, preferably starting at the first page of it
(rather than just the windows forms page) and taking it a bit at a
time. Threading is fundamentally pretty tricky, but it's very useful
too.
 
A

Arun Kumar

I know, its not true. Its sample app and was trying thing out.

Thanks for your response.

Arun
 
J

Jon Skeet [C# MVP]

DotNet Coder said:
Hey Jon? Didn't you write an article on this very subject? I seem to
remember you mentioning an article sometime last year.

I'm not *sure* whether you're being deliberately ironic or not, but the
article the OP mentioned is mine :)
 
D

DotNet Coder

Delphi takes care of the complexities of threading in the background for
you, without you having to worry about. Think about both of these
statements:

"One of the really nice features of using Delphi for .NET, is that
delegate functions have been mapped to the address of operator (the @
sign). What is actually happening behind the scenes is that Delphi is
creating a delegate object. Suffice it to say that the code for
languages like C# are more verbose."

"When a worker thread needs to execute a method from the main thread,
the worker thread would block, waiting for the main thread to process
the request. New to TThread, the Queue method provides the ability to
asynchronously call methods in the main thread. By queuing the method
instead of blocking, allows the worker thread to continue without
waiting for the execution of the method placed on the queue. Eventually
the main thread is ready to process the method(s) on the queue, and the
entire queue is processed at once."

from http://bdn.borland.com/borcon2004/article/paper/0,1963,32225,00.html.

Seems to me, that even in Delphi, you do not directly touch controls on
the main thread. Delegates are created for the developer without the
developer actually having to worry about it. In C#, you have to create
your delegates and wire up the sync/async calls yourself.

HTH,
~d
 
D

DotNet Coder

ROFL... i couldn't remember if it was your's or not and I didn't follw
the link up. I guess the word "Duh" really applies here, hunh? (Next
time, I should really look at the url *before* clicking the link... lol)

~d
 
G

Guest

Listen bra... just call Invoke(). if you don't like it, go back to wack Delphi!

..NET is ill!!!!

Arun Kumar said:
I know, its not true. Its sample app and was trying thing out.

Thanks for your response.

Arun
 
A

Arun Kumar

Listen Bro, I can guess you never used Delphi!!! If you don't like to
comment then DON'T comment, Delphi or C# makes no diff... both rocks.

its the .Net platform I am talking about.

Be nice.

..Net rules when you use properly.




Delphi Hater said:
Listen bra... just call Invoke(). if you don't like it, go back to wack
Delphi!

.NET is ill!!!!
 
B

Bob Powell [MVP]

Read up on the InvokeRequired property and the Invoke and BeginInvoke
methods.

Basically you should not directly acces the UI thread's objects from a non
UI thread.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
W

Willy Denoyette [MVP]

Arun Kumar said:
Thanks for your response.

Yes. I know that. there is nothing called "carefully". I have worked on
Threads alot in Win32 and I know what will have happen.
True. its a sample, yes I am trying out things what i can and what i
cannot do in .Net and what are the limitations and I strong believe there
is nothing wrong in doing that and putting my words out here and get the
best out it.

Arun

These, what you call "limitations", are imposed by "Windows" (Win32), not by
..NET. "Window" handles (just like Win32 Mutexes) have thread affinity, and
as such they shouldn't be used from another thread than the owning thread
(the one that created the window). Every system or framework that runs on
top of this has to repect this very rule, failing to do so will fail sooner
or later.
Note that v2.0 will throw an exception when running your sample in debug
mode, or when the CheckForIllegalCrossThreadCalls property is set to true in
release mode.

Willy.
 

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

Similar Threads

Thread GC collection 6
Thread memory consumption 3
Returning value from MT - need help 5
Threading 8
Why do ManagedThreadId start counting from 3 5
SynchronizationContext question 2
Thread 1
Monitor.Pulse question 2

Top