Have a look at this article. I *HIGHLY* recommend it.
http://msdn.microsoft.com/msdnmag/is...g/default.aspx
It talks all about how to do multithreading with windows forms
controls. And it provides a great base class in the download
(AsyncOperation in Listing2 I believe) that you can inherit from to
create your own worker thread that can fire events back to a windows
forms, and a nice way to cancel the worker thread. I believe it will
provide everything you need, plus explain it much better than I could
do here. If you have any questions while / after reading the article
and looking at his code, I'd be more than happy to discuss here, as
would others on the ng.
Good luck,
Mike
"Drakier Dominaeus" <drakier@cox.net> wrote in message
news:ejHWa.27847$Je.23698@fed1read04...[color=blue]
> I'm not sure how the ManualResetEvents work. I've never used them[/color]
before, so[color=blue]
> I'm not sure what they are, or how they are used. If you could[/color]
explain that[color=blue]
> a little, and maybe include some of my source code modified to how[/color]
it should[color=blue]
> be, I think I'll understand it a bit better in context. From another[/color]
thread,[color=blue]
> I learned that I cannot control UI elements from other threads, and[/color]
someone[color=blue]
> else suggested I could use Invoke. I mainly want to know the proper[/color]
method[color=blue]
> so that I can learn right the first time and not get into bad[/color]
habits.[color=blue]
>
> -Drakier
>
> "Jonathan Schafer" <jschafer@*NOSPAM*brierley.a.b.c.com> wrote in[/color]
message[color=blue]
> news:458mivsd9pd3l4t0ndsdtipea67tedibm9@4ax.com...[color=green]
> > A couple things stick out.
> >
> > 1. You cannot update UI elements from any thread other than the[/color][/color]
one[color=blue][color=green]
> > that created the UI element. Since your form was created on the
> > Primary thread, only the primary thread can update the form and/or
> > it's child controls. Doing so from another thread leads to
> > inconsistent results at best.
> >
> > You would have to use Control.Invoke to synchronously call your
> > delegate on the other thread or Control.BeginInvoke to[/color][/color]
asynchronously[color=blue][color=green]
> > call it.
> >
> > Also, your method of cancelling the secondary thread is really not[/color][/color]
the[color=blue][color=green]
> > appropriate way to go. Consider using a ManualResetEvent and a
> > WaitOne call in your loop. When your Cancel button is clicked,[/color][/color]
set[color=blue][color=green]
> > the event. In your loop processing, you do a
> >
> > // Assume ev is a ManualResetEvent
> >
> > while (true)
> > {
> > if (ev.WaitOne(5000))
> > breakl // event was signalled
> >
> > ... // do other stuff here
> > }
> >
> > You can create the ManualResetEvent in your Form and pass it as a
> > parameter to your "Thread" class.
> >
> > Jonathan Schafer
> >
> >
> > On Fri, 1 Aug 2003 19:08:53 -0700, "Drakier Dominaeus"
> > <drakier@cox.net> wrote:
> >[color=darkred]
> > >This is my first time posting here, so please forgive me if I do[/color][/color][/color]
anything[color=blue][color=green][color=darkred]
> > >incorrectly.
> > >
> > >I've been learning C# and working with different things and[/color][/color][/color]
decided I[color=blue]
> wanted[color=green][color=darkred]
> > >to get into Multi-Threading. My problem is that I must not be[/color][/color][/color]
doing it[color=blue]
> right[color=green][color=darkred]
> > >because only some of the stuff works as would be expected. I'll[/color][/color][/color]
post what[color=blue][color=green][color=darkred]
> > >exactly is happening, then I'll post the sample code I'm using[/color][/color][/color]
that is[color=blue][color=green][color=darkred]
> > >giving me the problems. I'm sure its something I've overlooked,[/color][/color][/color]
or I'm[color=blue]
> just[color=green][color=darkred]
> > >doing it completely wrong.
> > >
> > >Below is the code for my sample application. It has 2 buttons and[/color][/color][/color]
a[color=blue]
> label.[color=green][color=darkred]
> > >Basically, the thread is just supposed to make the label visible[/color][/color][/color]
and loop[color=blue][color=green][color=darkred]
> > >every 5 seconds. the top button starts the thread going, and the[/color][/color][/color]
bottom[color=blue][color=green][color=darkred]
> > >button calls the Cancel() method which turns off blocking and[/color][/color][/color]
allows the[color=blue][color=green][color=darkred]
> > >thread to exit properly. The problem is that the label sometimes[/color][/color][/color]
appears[color=blue]
> to[color=green][color=darkred]
> > >become visible, but if the form is minimized, or a window is[/color][/color][/color]
moved over[color=blue]
> it,[color=green][color=darkred]
> > >you'll see its really not. Also.. the Form seems to become VERY[/color][/color][/color]
laggy and[color=blue][color=green][color=darkred]
> > >acts as though its processing REALLY hard (although its not as[/color][/color][/color]
the[color=blue][color=green][color=darkred]
> > >taskmanager says its using very little CPU).
> > >
> > >You may ask why I'm using Events and that is because what I plan[/color][/color][/color]
on doing[color=blue]
> is[color=green][color=darkred]
> > >making a worker thread that will send periodic updates back to[/color][/color][/color]
the main[color=blue][color=green][color=darkred]
> > >program to progress a status bar. Why I'm using threads and[/color][/color][/color]
events isn't[color=blue][color=green][color=darkred]
> > >important. What is important is that I must be doing something[/color][/color][/color]
wrong, and[color=blue]
> I[color=green][color=darkred]
> > >want to learn how I should do it correctly.
> > >
> > >Anyway.. that is my problem.. here is the source...
> > >
> > >
> > >=============================
> > >
> > >using System;
> > >using System.Drawing;
> > >using System.Collections;
> > >using System.ComponentModel;
> > >using System.Windows.Forms;
> > >using System.Data;
> > >using System.Threading;
> > >
> > >namespace ThreadTest
> > >{
> > > #region TestEventHandler
> > > public delegate void TestEventHandler(object sender,[/color][/color][/color]
TestEventArgs[color=blue]
> e);[color=green][color=darkred]
> > > public class TestEventArgs : EventArgs
> > > {
> > > public bool ShowLabel = false;
> > > public TestEventArgs(bool bShowLabel) { ShowLabel =[/color][/color]
> bShowLabel; }[color=green][color=darkred]
> > > }
> > > #endregion
> > > #region Test Thread
> > > public class clsThreadTest
> > > {
> > > public event TestEventHandler ShowLabel;
> > > private bool blocked = false;
> > > private Thread TestThread = null;
> > > public clsThreadTest() { }
> > > public void SetLabel(bool bVisible)
> > > {
> > > if (ShowLabel != null)
> > > {
> > > TestEventArgs tea = new[/color][/color][/color]
TestEventArgs(bVisible);[color=blue][color=green][color=darkred]
> > > ShowLabel(this, tea);
> > > }
> > > }
> > > public void Start()
> > > {
> > > if (!blocked)
> > > {
> > > blocked = !blocked;
> > > TestThread = new Thread(new[/color][/color][/color]
ThreadStart(RunTest));[color=blue][color=green][color=darkred]
> > > TestThread.ApartmentState =[/color][/color][/color]
ApartmentState.MTA;[color=blue][color=green][color=darkred]
> > > TestThread.Priority = ThreadPriority.Lowest;
> > > TestThread.Name = "Test Thread";
> > > TestThread.Start();
> > > }
> > > }
> > >
> > > public void Cancel()
> > > {
> > > blocked = false;
> > > }
> > > public void RunTest()
> > > {
> > > while (blocked)
> > > {
> > > SetLabel(true);
> > > Thread.Sleep(5000);
> > > }
> > > }
> > > }
> > > #endregion
> > > public class Form1 : System.Windows.Forms.Form
> > > {
> > > private clsThreadTest cThreadTest = new clsThreadTest();
> > > private System.Windows.Forms.Label label1;
> > > private System.Windows.Forms.Button button1;
> > > private System.Windows.Forms.Button button2;
> > > private System.ComponentModel.Container components =[/color][/color][/color]
null;[color=blue][color=green][color=darkred]
> > >
> > > public Form1()
> > > {
> > > InitializeComponent();
> > > cThreadTest.ShowLabel += new
> > >TestEventHandler(cThreadTest_ShowLabel);
> > >
> > > }
> > >
> > > public void cThreadTest_ShowLabel(object sender,[/color][/color][/color]
TestEventArgs[color=blue]
> tea)[color=green][color=darkred]
> > > {
> > > label1.Visible = tea.ShowLabel;
> > > label1.Refresh();
> > > this.Refresh();
> > > }
> > >
> > > protected override void Dispose( bool disposing )
> > > {
> > > if( disposing )
> > > {
> > > if (components != null)
> > > {
> > > components.Dispose();
> > > }
> > > }
> > > base.Dispose( disposing );
> > > }
> > >
> > > #region Windows Form Designer generated code
> > > /// <summary>
> > > /// Required method for Designer support - do not modify
> > > /// the contents of this method with the code editor.
> > > /// </summary>
> > > private void InitializeComponent()
> > > {
> > > this.label1 = new System.Windows.Forms.Label();
> > > this.button1 = new System.Windows.Forms.Button();
> > > this.button2 = new System.Windows.Forms.Button();
> > > this.SuspendLayout();
> > > //
> > > // label1
> > > //
> > > this.label1.Font = new[/color][/color][/color]
System.Drawing.Font("Microsoft Sans[color=blue][color=green][color=darkred]
> > >Serif", 12F, System.Drawing.FontStyle.Bold,
> > >System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
> > > this.label1.ForeColor = System.Drawing.Color.Red;
> > > this.label1.Location = new System.Drawing.Point(42,[/color][/color][/color]
12);[color=blue][color=green][color=darkred]
> > > this.label1.Name = "label1";
> > > this.label1.Size = new System.Drawing.Size(108,[/color][/color][/color]
24);[color=blue][color=green][color=darkred]
> > > this.label1.TabIndex = 0;
> > > this.label1.Text = "Hello!";
> > > this.label1.TextAlign =
> > >System.Drawing.ContentAlignment.MiddleCenter;
> > > this.label1.Visible = false;
> > > //
> > > // button1
> > > //
> > > this.button1.Location = new[/color][/color][/color]
System.Drawing.Point(186, 6);[color=blue][color=green][color=darkred]
> > > this.button1.Name = "button1";
> > > this.button1.Size = new System.Drawing.Size(96,[/color][/color][/color]
18);[color=blue][color=green][color=darkred]
> > > this.button1.TabIndex = 1;
> > > this.button1.Text = "Start Thread";
> > > this.button1.Click += new
> > >System.EventHandler(this.button1_Click);
> > > //
> > > // button2
> > > //
> > > this.button2.Location = new[/color][/color][/color]
System.Drawing.Point(186, 24);[color=blue][color=green][color=darkred]
> > > this.button2.Name = "button2";
> > > this.button2.Size = new System.Drawing.Size(96,[/color][/color][/color]
18);[color=blue][color=green][color=darkred]
> > > this.button2.TabIndex = 2;
> > > this.button2.Text = "Queue Stop";
> > > this.button2.Click += new
> > >System.EventHandler(this.button2_Click);
> > > //
> > > // Form1
> > > //
> > > this.AutoScaleBaseSize = new[/color][/color][/color]
System.Drawing.Size(5, 13);[color=blue][color=green][color=darkred]
> > > this.ClientSize = new System.Drawing.Size(292, 45);
> > > this.Controls.AddRange(new[/color][/color][/color]
System.Windows.Forms.Control[] {[color=blue][color=green][color=darkred]
> > >
> > >this.button2,
> > >
> > >this.button1,
> > >
> > >this.label1});
> > > this.Name = "Form1";
> > > this.Text = "Form1";
> > > this.ResumeLayout(false);
> > >
> > > }
> > > #endregion
> > >
> > > [STAThread]
> > > static void Main()
> > > {
> > > Application.Run(new Form1());
> > > }
> > >
> > > private void button1_Click(object sender,[/color][/color][/color]
System.EventArgs e)[color=blue][color=green][color=darkred]
> > > {
> > > cThreadTest.Start();
> > > }
> > >
> > > private void button2_Click(object sender,[/color][/color][/color]
System.EventArgs e)[color=blue][color=green][color=darkred]
> > > {
> > > cThreadTest.Cancel();
> > > }
> > > }
> > >}
> > >[/color]
> >[/color]
>
>[/color]