Csharp/C Sharp/GUI Windows Form/Thread and UI

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Background processing in a thread.

<source lang="csharp">

using System; using System.Drawing; using System.Collections; using System.ruponentModel; using System.Windows.Forms; using System.Data; using System.Threading; public class Form1 : System.Windows.Forms.Form {

   private System.Windows.Forms.Label label1;
   private System.Windows.Forms.Button button1;
   private System.Windows.Forms.Label ValueLabel;
   private System.Windows.Forms.Button button2;
   private System.ruponentModel.Container components = null;
   private Thread fThread;
   private int fValue;
   public Form1() {
       fValue = 0;
       this.label1 = new System.Windows.Forms.Label();
       this.button1 = new System.Windows.Forms.Button();
       this.ValueLabel = new System.Windows.Forms.Label();
       this.button2 = new System.Windows.Forms.Button();
       this.SuspendLayout();
       this.label1.Location = new System.Drawing.Point(24, 32);
       this.label1.Size = new System.Drawing.Size(80, 16);
       this.label1.Text = "Value of Data:";
       this.button1.Location = new System.Drawing.Point(232, 32);
       this.button1.Text = "&Update";
       this.button1.Click += new
            System.EventHandler(this.button1_Click);
       this.ValueLabel.Location = new System.Drawing.Point(120, 32);
       this.button2.Location = new System.Drawing.Point(104, 88);
       this.button2.Name = "button2";
       this.button2.RightToLeft =
            System.Windows.Forms.RightToLeft.No;
       this.button2.Size = new System.Drawing.Size(96, 23);
       this.button2.Text = "Start Thread";
       this.button2.Click += new
            System.EventHandler(this.button2_Click);
       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
       this.ClientSize = new System.Drawing.Size(336, 141);
       this.Controls.AddRange(new System.Windows.Forms.Control[] {
         this.button2,
         this.ValueLabel,
         this.button1,
         this.label1});
       this.ResumeLayout(false);
   }
   [STAThread]
   static void Main() {
       Application.Run(new Form1());
   }
   private void ThreadProc() {
       while (fValue < 1000) {
           Thread.Sleep(1000);
           fValue++;
       }
   }
   private void button2_Click(object sender, System.EventArgs e) {
       fThread = new Thread(new ThreadStart(ThreadProc));
       fThread.IsBackground = true;
       fThread.Start();
   }
   private void button1_Click(object sender, System.EventArgs e) {
       this.ValueLabel.Text = fValue.ToString();
   }

}

</source>


Starting and stopping a thread.

<source lang="csharp"> using System; using System.Drawing; using System.Collections; using System.ruponentModel; using System.Windows.Forms; using System.Data; using System.Threading; public class Form1 : System.Windows.Forms.Form {

   private System.Windows.Forms.Button button1;
   private System.Windows.Forms.Button button2;
   private System.Windows.Forms.Label label1;
   private System.Windows.Forms.Label label2;
   private System.Windows.Forms.Label NumThreads;
   private System.Windows.Forms.Label Counter;
   private int fCounter;
   private ArrayList fThreadList;
   private System.ruponentModel.Container components = null;
   public Form1() {
       InitializeComponent();
       fThreadList = new ArrayList();
   }
   protected override void Dispose(bool disposing) {
       if (disposing) {
           if (components != null) {
               components.Dispose();
               for (int i = 0; i < fThreadList.Count; ++i) {
                   Thread fThread = (Thread)fThreadList[i];
                   fThread.Abort();
               }
           }
       }
       base.Dispose(disposing);
   }
   private void InitializeComponent() {
       this.button1 = new System.Windows.Forms.Button();
       this.button2 = new System.Windows.Forms.Button();
       this.label1 = new System.Windows.Forms.Label();
       this.label2 = new System.Windows.Forms.Label();
       this.NumThreads = new System.Windows.Forms.Label();
       this.Counter = new System.Windows.Forms.Label();
       this.SuspendLayout();
       this.button1.Location = new System.Drawing.Point(32, 104);
       this.button1.Name = "button1";
       this.button1.TabIndex = 0;
       this.button1.Text = "&Start";
       this.button1.Click += new
            System.EventHandler(this.button1_Click);
       this.button2.Location = new System.Drawing.Point(136, 104);
       this.button2.Name = "button2";
       this.button2.Size = new System.Drawing.Size(88, 24);
       this.button2.TabIndex = 1;
       this.button2.Text = "&Stop";
       this.button2.Click += new
            System.EventHandler(this.button2_Click);
       this.label1.Location = new System.Drawing.Point(32, 40);
       this.label1.Name = "label1";
       this.label1.Size = new System.Drawing.Size(152, 16);
       this.label1.TabIndex = 2;
       this.label1.Text = "Number of Threads Running:";
       this.label2.Location = new System.Drawing.Point(32, 64);
       this.label2.Name = "label2";
       this.label2.Size = new System.Drawing.Size(100, 16);
       this.label2.TabIndex = 3;
       this.label2.Text = "Counter:";
       this.NumThreads.Location = new System.Drawing.Point(192, 40);
       this.NumThreads.Name = "NumThreads";
       this.NumThreads.Size = new System.Drawing.Size(64, 16);
       this.NumThreads.TabIndex = 4;
       this.Counter.Location = new System.Drawing.Point(192, 64);
       this.Counter.Name = "Counter";
       this.Counter.Size = new System.Drawing.Size(64, 16);
       this.Counter.TabIndex = 5;
       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
       this.ClientSize = new System.Drawing.Size(272, 165);
       this.Controls.AddRange(new System.Windows.Forms.Control[] {
       this.Counter,
       this.NumThreads,
       this.label2,
       this.label1,
       this.button2,
       this.button1});
       this.ResumeLayout(false);
   }
   [STAThread]
   static void Main() {
       Application.Run(new Form1());
   }
   protected void ThreadFunc() {
       Boolean done = false;
       while (!done) {
           Thread.Sleep(1000);
           fCounter++;
           this.Counter.Text = fCounter.ToString();
       }
   }
   private void button1_Click(object sender, System.EventArgs e) {
       Thread fThread = new Thread(new ThreadStart(ThreadFunc));
       fThread.Start();
       fThreadList.Add(fThread);
       this.NumThreads.Text = fThreadList.Count.ToString();
   }
   private void button2_Click(object sender, System.EventArgs e) {
       Thread fThread = (Thread)fThreadList[fThreadList.Count - 1];
       fThread.Abort();
       fThreadList.Remove(fThread);
       this.NumThreads.Text = fThreadList.Count.ToString();
   }

}

</source>


Talking to a visual element in a background thread.

<source lang="csharp">

using System; using System.Drawing; using System.Collections; using System.ruponentModel; using System.Windows.Forms; using System.Data; using System.Threading; public class Form1 : System.Windows.Forms.Form {

   private System.Windows.Forms.ProgressBar progressBar1;
   private System.Windows.Forms.Button button1;
   private System.Windows.Forms.Button button2;
   private Thread fThread = null;
   private System.ruponentModel.Container components = null;
   public Form1() {
       this.progressBar1 = new System.Windows.Forms.ProgressBar();
       this.button1 = new System.Windows.Forms.Button();
       this.button2 = new System.Windows.Forms.Button();
       this.SuspendLayout();
       this.progressBar1.Location = new System.Drawing.Point(24, 32);
       this.progressBar1.Name = "progressBar1";
       this.progressBar1.Size = new System.Drawing.Size(264, 23);
       this.progressBar1.TabIndex = 0;
       this.button1.Location = new System.Drawing.Point(24, 80);
       this.button1.Size = new System.Drawing.Size(136, 40);
       this.button1.Text = "Start Thread";
       this.button1.Click += new
            System.EventHandler(this.button1_Click);
       this.button2.Location = new System.Drawing.Point(168, 80);
       this.button2.Size = new System.Drawing.Size(120, 40);
       this.button2.Text = "Stop Thread";
       this.button2.Click += new
            System.EventHandler(this.button2_Click);
       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
       this.ClientSize = new System.Drawing.Size(704, 429);
       this.Controls.AddRange(new System.Windows.Forms.Control[] {
         this.button2,
         this.button1,
         this.progressBar1});
       this.ResumeLayout(false);
   }
   protected override void Dispose(bool disposing) {
       if (fThread != null) {
           fThread.Interrupt();
           fThread = null;
       }
   }
   [STAThread]
   static void Main() {
       Application.Run(new Form1());
   }
   private void UpdateProgress() {
       if (progressBar1.Value == progressBar1.Maximum) {
           progressBar1.Value = progressBar1.Minimum;
       }
       progressBar1.PerformStep();
   }
   public void ThreadProc() {
       try {
           MethodInvoker mi = new MethodInvoker(this.UpdateProgress);
           while (true) {
               this.BeginInvoke(mi);
               Thread.Sleep(500);
           }
       } catch (ThreadInterruptedException e) {
           Console.WriteLine(
             "Interruption Exception in Thread: {0}",
                 e);
       } catch (Exception we) {
           Console.WriteLine("Exception in Thread: {0}", we);
       }
   }
   private void button1_Click(object sender, System.EventArgs e) {
       fThread = new Thread(new ThreadStart(ThreadProc));
       fThread.IsBackground = true;
       fThread.Start();
   }
   private void button2_Click(object sender, System.EventArgs e) {
       fThread.Interrupt();
       fThread = null;
   }

}

</source>


Thread and UI Demo

<source lang="csharp"> using System; using System.Threading; using System.Drawing; using System.Collections; using System.ruponentModel; using System.Windows.Forms; using System.Data; public struct MyData {

   public double pi;
   public int iters;

} public class Calc {

   private double _pi;
   private int _iters;
   private readonly int TotalIters;
   public Calc(int it) {
       _iters = 1;
       _pi = 0;
       TotalIters = it;
   }
   public MyData PI {
       get {
           MyData pi = new MyData();
           lock (this) {
               pi.pi = _pi;
               pi.iters = _iters;
           }
           return pi;
       }
   }
   public Thread MakeThread() {
       return new Thread(new ThreadStart(this.ThreadStarter));
   }
   private void calculate() {
       double series = 0;
       do {
           series ++;
           lock (this) {
               _iters += 4;
               _pi = series * 4;
           }
       } while (_iters < TotalIters);
   }
   private void ThreadStarter() {
       try {
           calculate();
       } catch (ThreadAbortException e) {
           Console.WriteLine("ThreadAbortException");
       }
   }

} public class Form1 : System.Windows.Forms.Form {

   private System.Windows.Forms.Label label1;
   private System.Windows.Forms.TextBox PiValue;
   private System.Windows.Forms.Label label2;
   private System.Windows.Forms.TextBox Iteratons;
   private Calc pi = new Calc(100000000);
   private Thread calcThread = null;
   private System.Windows.Forms.Timer timer1;
   private System.Windows.Forms.Button StopButton;
   private System.Windows.Forms.Button Pause;
   private System.ruponentModel.IContainer components;
   public Form1() {
       this.label1 = new System.Windows.Forms.Label();
       this.label2 = new System.Windows.Forms.Label();
       this.Pause = new System.Windows.Forms.Button();
       this.PiValue = new System.Windows.Forms.TextBox();
       this.StopButton = new System.Windows.Forms.Button();
       this.timer1 = new System.Windows.Forms.Timer(this.ruponents);
       this.Iteratons = new System.Windows.Forms.TextBox();
       this.SuspendLayout();
       // 
       // label1
       // 
       this.label1.Location = new System.Drawing.Point(8, 24);
       this.label1.Name = "label1";
       this.label1.TabIndex = 0;
       this.label1.Text = "Value  of PI:";
       // 
       // label2
       // 
       this.label2.Location = new System.Drawing.Point(8, 72);
       this.label2.Name = "label2";
       this.label2.TabIndex = 2;
       this.label2.Text = "Iterations:";
       // 
       // Pause
       // 
       this.Pause.Location = new System.Drawing.Point(24, 112);
       this.Pause.Name = "Pause";
       this.Pause.TabIndex = 5;
       this.Pause.Text = "Pause";
       this.Pause.Click += new System.EventHandler(this.Pause_Click);
       // 
       // PiValue
       // 
       this.PiValue.Location = new System.Drawing.Point(128, 24);
       this.PiValue.Name = "PiValue";
       this.PiValue.ReadOnly = true;
       this.PiValue.Size = new System.Drawing.Size(136, 20);
       this.PiValue.TabIndex = 1;
       this.PiValue.Text = "";
       // 
       // StopButton
       // 
       this.StopButton.Location = new System.Drawing.Point(200, 112);
       this.StopButton.Name = "StopButton";
       this.StopButton.TabIndex = 4;
       this.StopButton.Text = "Stop";
       this.StopButton.Click += new System.EventHandler(this.StopButton_Click);
       // 
       this.timer1.Enabled = true;
       this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
       // 
       this.Iteratons.Location = new System.Drawing.Point(128, 72);
       this.Iteratons.Name = "Iteratons";
       this.Iteratons.ReadOnly = true;
       this.Iteratons.TabIndex = 3;
       this.Iteratons.Text = "";
       // 
       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
       this.ClientSize = new System.Drawing.Size(292, 149);
       this.Controls.AddRange(new System.Windows.Forms.Control[]  {
                                                                 this.Pause,
                                                                 this.StopButton,
                                                                 this.Iteratons,
                                                                 this.label2,
                                                                 this.PiValue,
                                                                 this.label1});
       this.Load += new System.EventHandler(this.Form1_Load);
       this.Closed += new System.EventHandler(this.Form1_Closed);
       this.ResumeLayout(false);
   }
   [STAThread]
   static void Main() {
       Application.Run(new Form1());
   }
   private void Form1_Load(object sender, System.EventArgs e) {
       calcThread = pi.MakeThread();
       calcThread.Priority = ThreadPriority.Lowest;
       calcThread.Start();
   }
   private void timer1_Tick(object sender, System.EventArgs e) {
       if (this.Pause.Text == "Pause") {
           MyData p = pi.PI;
           this.PiValue.Text = p.pi.ToString();
           this.Iteratons.Text = p.iters.ToString();
       }
       if (calcThread.IsAlive == false) {
           StopButton.Enabled = false;
           Pause.Enabled = false;
           timer1.Enabled = false;
           calcThread = null;
       }
   }
   private void StopButton_Click(object sender, System.EventArgs e) {
       StopButton.Enabled = false;
       Pause.Enabled = false;
       timer1.Enabled = false;
       calcThread.Abort();
       calcThread.Join();
       calcThread = null;
   }
   private void Pause_Click(object sender, System.EventArgs e) {
       if (this.Pause.Text == "Pause") {
           calcThread.Suspend();
           this.Pause.Text = "Resume";
           this.StopButton.Enabled = false;
       } else {
           calcThread.Resume();
           this.Pause.Text = "Pause";
           this.StopButton.Enabled = true;
       }
   }
   private void Form1_Closed(object sender, System.EventArgs e) {
       if (calcThread != null) {
           calcThread.Abort();
           calcThread.Join();
       }
   }

}

</source>