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

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

Background processing in a thread.

 

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();
    }
}


Starting and stopping a thread.

 
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();
    }
}


Talking to a visual element in a background thread.

 

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;
    }
}


Thread and UI Demo

 
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();
        }
    }
}