Thread 的 _event.Set(),_event.Reset();_event.WaitOne(); 用法示例

此博客展示了Windows Forms中跨线程访问UI的代码示例。通过创建线程,在点击按钮时启动线程,利用Invoke方法实现跨线程更新UI控件属性,如禁用按钮、更新按钮文本等,还使用ManualResetEvent控制线程的暂停和恢复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsForms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Thread Thread_T9; //除尘机通讯线程
        ManualResetEvent _event = new ManualResetEvent(true);

        private void button1_Click(object sender, EventArgs e)
        {
            //启动一个线程  
            //new Thread(ThreadProc).Start();
            Thread_T9 = new Thread(ThreadProc);// (new ThreadStart(fSingleCameraProcess));
            Thread_T9.Start();  //启动线程
            Thread_T9.IsBackground = true;
        }

        //线程函数  
        public void ThreadProc()
        {
            while (true)
            {
                 _event.WaitOne();
                //this.Invoke就是跨线程访问ui的方法,也是本文的范例  
                //首先invoke一个匿名委托,将button对象禁用  
                this.Invoke((EventHandler)delegate
            {
                button1.Enabled = false;
            });

                //记录一个时间戳,以演示倒计时效果  
                int tick = Environment.TickCount;
                while (Environment.TickCount - tick < 1000)
                {
                    //跨线程调用更新窗体上控件的属性,这里是更新这个按钮对象的Text属性  
                    this.Invoke((EventHandler)delegate
                    {
                        button1.Text = (1000 - Environment.TickCount + tick).ToString() + "微秒后开始更新";
                    });
                    //做一个延迟,避免太快了,视觉效果不好。  
                    Thread.Sleep(100);
                }
                //演示,10次数字递增显示  
                for (int i = 0; i < 10; i++)
                {
                    this.Invoke((EventHandler)delegate
                    {
                        button1.Text = i.ToString();
                    });
                    Thread.Sleep(200);
                }
                //虽然不是循环内,请不要忘记,你的调用依然在辅助线程中,所以,还是需要invoke的。  
                //还原状态,设置按钮的文本为初始状态,设置按钮可用。  
                this.Invoke((EventHandler)delegate
                {
                    button1.Text = "点击开始测试";
                    button1.Enabled = true;
                });
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            /*
             */
            this.button1.Click += new System.EventHandler(this.button1_Click);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _event.Set();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            _event.Reset();
        }
    }
}
 

代码解释using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //using System.Windows.Controls; using System.Windows.Threading; using System.ComponentModel; namespace EMCL { public enum ETestResult { TR_Fail = 0, TR_Pass = 1, TR_Done = 2, TR_Continue = 3, TR_Error = 4, TR_End = 5, } public enum ETestMode { Mode1_1 = 11, Mode1_2 = 12, Mode2_1 = 21, Mode2_2 = 22, Mode3_1 = 31, Mode3_2 = 32 } public enum ETestStage { Stage_PreTest = 0, Stage_PostTest = 1, Stage_CycleTest = 2 } public class TestExecutor : IDisposable { public TestExecutor() { TargetTestCycle = 1; TargetTestTime = new TimeSpan(0); } public virtual void Dispose() { } public int TargetTestCycle { get; set; } public TimeSpan TargetTestTime { get; set; } public virtual ETestResult Execute(TaskManager tm) { return ETestResult.TR_End; } } public class TestMode : TestExecutor { public TestMode() { Mode = ETestMode.Mode3_2; CycleInterval = 0; } public string Name { get; set; } public ETestMode Mode { get; set; } double CycleInterval { get; set; } public override ETestResult Execute(TaskManager tm) { DateTime tmBeg = DateTime.Now; ETestResult tr = tm.OnModeBegin(this); if (ETestResult.TR_Continue < tr) { tm.OnModeEnd(this); return tr; } int nCycleInv = (int)(CycleInterval * 1000); if (base.TargetTestCycle >= 0) { int nCycleCnt = base.TargetTestCycle; if (0 == base.TargetTestCycle) nCycleCnt = int.MaxValue; for (int c = 0; c < nCycleCnt; c++) { tr = tm.ExecCycle(); if (ETestResult.TR_Continue < tr) break; if (nCycleInv > 0) System.Threading.Thread.Sleep(nCycleInv); } } else if (base.TargetTestTime > new TimeSpan(0)) { while (tmBeg + base.TargetTestTime > DateTime.Now) { tr = tm.ExecCycle(); if (ETestResult.TR_Continue < tr) break; if (nCycleInv > 0) System.Threading.Thread.Sleep(nCycleInv); } } tm.OnModeEnd(this); return tr; } } public class TestTask : TestExecutor { protected List<TestMode> m_ModeList = null; public TestTask() { m_ModeList = new List<TestMode>(); } public override void Dispose() { RemoveAllMode(); } public string Name { get; set; } public List<TestMode> GetModeList() { return m_ModeList; } public void RemoveAllMode() { foreach (TestMode mode in m_ModeList) { mode.Dispose(); } m_ModeList.Clear(); } public void AddMode(TestMode tm) { m_ModeList.Add(tm); } public override ETestResult Execute(TaskManager tm) { DateTime tmBeg = DateTime.Now; ETestResult tr = tm.OnTaskBegin(this); if (ETestResult.TR_Continue < tr) { tm.OnTaskEnd(this); return tr; } if (base.TargetTestCycle >= 0) { int nCycleCnt = base.TargetTestCycle; if (0 == base.TargetTestCycle) nCycleCnt = int.MaxValue; for (int c = 0; c < nCycleCnt; c++) { tr = ExecMode(tm); if (ETestResult.TR_Continue < tr) break; } } else if (base.TargetTestTime > new TimeSpan(0)) { while (tmBeg + base.TargetTestTime > DateTime.Now) { tr = ExecMode(tm); if (ETestResult.TR_Continue < tr) break; } } tm.OnTaskEnd(this); return tr; } public virtual ETestResult ExecMode(TaskManager tm) { ETestResult tr = ETestResult.TR_Done; foreach (TestMode mode in m_ModeList) { tr = mode.Execute(tm); if (ETestResult.TR_Continue < tr) { break; } } return tr; } } public class TaskManager : TestExecutor { protected List<TestTask> m_TaskList = null; protected DateTime m_tmTestStart; protected DateTime m_tmTestStop; protected volatile int m_tsCycleTime; protected DateTime m_tmCycleBegin; protected double m_lfTotalCycleTime; protected volatile int m_nExecCycleNo = 0; protected volatile Boolean m_KeepWorking; protected volatile ETestStage m_TestStage; public TaskManager() { DutCount = 1; m_TaskList = new List<TestTask>(); m_KeepWorking = false; } public override void Dispose() { RemoveAllTask(); } public int DutCount { get; set; } public int CurrentTestCycle { get { return m_nExecCycleNo; } } public DateTime BeginTestTime { get { return m_tmTestStart; } } public DateTime EndTestTime { get { return m_tmTestStop; } } public TimeSpan TotalTestTime { get { if (m_tmTestStop > m_tmTestStart) return TimeSpan.FromSeconds((int)(m_tmTestStop - m_tmTestStart).TotalSeconds); else return TimeSpan.FromSeconds((int)(DateTime.Now - m_tmTestStart).TotalSeconds); } } public TimeSpan CycleTime { get { return TimeSpan.FromMilliseconds(m_tsCycleTime); } } public ETestStage TestStage { get { return m_TestStage; } } public List<TestTask> GetTaskList() { return m_TaskList; } public TestTask GetTask(int idx) { return m_TaskList[idx]; } public void RemoveAllTask() { foreach (TestTask task in m_TaskList) { task.Dispose(); } m_TaskList.Clear(); } public void AddTask(TestTask tt) { m_TaskList.Add(tt); } public void Execute() { m_tsCycleTime = 0; m_lfTotalCycleTime = 0; m_tmTestStart = DateTime.Now; //////////////////////////////////////////////////// m_tmTestStop = m_tmTestStart; m_KeepWorking = true; if (ETestResult.TR_Continue < OnTestBegin()) { OnTestEnd(); return; } if (!m_KeepWorking) { OnTestEnd(); return; } ExecTask(this); OnTestEnd(); } public virtual ETestResult ExecTask(TaskManager tm) { m_TestStage = ETestStage.Stage_CycleTest; ETestResult tr = ETestResult.TR_Done; foreach (TestTask task in m_TaskList) { tr = task.Execute(tm); if (ETestResult.TR_Continue < tr) { break; } } return tr; } public virtual ETestResult ExecCycle() { int nCurCycle = m_nExecCycleNo++; ETestResult tr = OnCycleBegin(nCurCycle); if (ETestResult.TR_Continue < tr) { OnCycleEnd(nCurCycle); return tr; } for (int dut = 0; dut < DutCount; dut++) { tr = ExecDut(nCurCycle, dut); if (ETestResult.TR_Continue < tr) { break; } } OnCycleEnd(nCurCycle); if (!m_KeepWorking) tr = ETestResult.TR_End; return tr; } public virtual ETestResult ExecDut(int nCurCycle, int dut) { ETestResult tr = OnDutBegin(dut); if (ETestResult.TR_Continue < tr) { OnDutEnd(dut); return tr; } tr = ExecTestPlan(nCurCycle, dut); OnDutEnd(dut); return tr; } public virtual ETestResult ExecTestPlan(int nCurCycle, int dut) { ETestResult tr = OnTestPlanBegin(nCurCycle, dut); if (ETestResult.TR_Continue < tr) { OnTestPlanEnd(nCurCycle, dut); return tr; } tr = TestPlan(nCurCycle, dut); OnTestPlanEnd(nCurCycle, dut); return tr; } public virtual ETestResult TestPlan(int nCurCycle, int dut) { return ETestResult.TR_Done; } public virtual ETestResult OnTestBegin() { m_TestStage = ETestStage.Stage_PreTest; return ETestResult.TR_Done; } public virtual ETestResult OnTestEnd() { m_tmTestStop = DateTime.Now; m_TestStage = ETestStage.Stage_PostTest; return ETestResult.TR_Done; } public virtual ETestResult OnTaskBegin(TestTask tt) { return ETestResult.TR_Done; } public virtual ETestResult OnTaskEnd(TestTask tt) { return ETestResult.TR_Done; } public virtual ETestResult OnModeBegin(TestMode tm) { return ETestResult.TR_Done; } public virtual ETestResult OnModeEnd(TestMode tm) { return ETestResult.TR_Done; } public virtual ETestResult OnCycleBegin(int idx) { m_tmCycleBegin = DateTime.Now; return ETestResult.TR_Done; } public virtual ETestResult OnCycleEnd(int idx) { m_lfTotalCycleTime += (DateTime.Now - m_tmCycleBegin).TotalMilliseconds; m_tsCycleTime = (int)(m_lfTotalCycleTime / CurrentTestCycle); return ETestResult.TR_Done; } public virtual ETestResult OnDutBegin(int idx) { return ETestResult.TR_Done; } public virtual ETestResult OnDutEnd(int idx) { return ETestResult.TR_Done; } public virtual ETestResult OnTestPlanBegin(int nCurCycle, int dut) { return ETestResult.TR_Done; } public virtual ETestResult OnTestPlanEnd(int nCurCycle, int dut) { return ETestResult.TR_Done; } } public class TestManager : TaskManager, IDisposable { // The Test thread //protected Thread m_thread = null; AutoResetEvent evtThdEnd = new AutoResetEvent(false); BackgroundWorker backgroundWorker1 = null; public TestManager() { } public override void Dispose() { base.Dispose(); } public virtual bool TM_Init() { return true; } protected virtual void DoEvents() { } public virtual bool TM_IsStart() { if (null == backgroundWorker1 || !backgroundWorker1.IsBusy) return false; return true; } public virtual bool TM_Start() { //// create a anonymous function to call DoSomthing //ParameterizedThreadStart threadDelegate = delegate (object obj) //{ // TestManager This = (TestManager)obj; // This.Execute(); // This.ThreadEnd(); //}; //// Do Somthing in a thread //m_thread = new Thread(threadDelegate); //m_thread.IsBackground = true; if (backgroundWorker1 != null && backgroundWorker1.IsBusy) return false; m_nExecCycleNo = 0; m_tmTestStart = DateTime.Now; evtThdEnd.Reset(); //m_thread.Start(this); backgroundWorker1 = new BackgroundWorker(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; backgroundWorker1.DoWork += backgroundWorker1_DoWork; if (backgroundWorker1.IsBusy != true) { // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(); } //private void cancelAsyncButton_Click(object sender, EventArgs e) //{ // if (backgroundWorker1.WorkerSupportsCancellation == true) // { // // Cancel the asynchronous operation. // backgroundWorker1.CancelAsync(); // } return true; } public virtual bool TM_Stop() { if (null == backgroundWorker1) return false; if (!backgroundWorker1.IsBusy) return true; m_KeepWorking = false; bool bEnd = false; //bEnd = evtThdEnd.WaitOne(10); //while (!bEnd && m_thread.IsAlive) //{ // DoEvents(); // bEnd = evtThdEnd.WaitOne(10); //} if (backgroundWorker1.WorkerSupportsCancellation == true) { // Cancel the asynchronous operation. backgroundWorker1.CancelAsync(); } bEnd = evtThdEnd.WaitOne(10); while (!bEnd && backgroundWorker1.IsBusy) { DoEvents(); bEnd = evtThdEnd.WaitOne(10); } return true; } void ThreadEnd() { evtThdEnd.Set(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; Execute(); ThreadEnd(); //for (int i = 1; i <= 10; i++) //{ // if (worker.CancellationPending == true) // { // e.Cancel = true; // break; // } // else // { // // Perform a time consuming operation and report progress. // System.Threading.Thread.Sleep(500); // worker.ReportProgress(i * 10); // } //} } // This event handler updates the progress. private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { //resultLabel.Text = (e.ProgressPercentage.ToString() + "%"); } // This event handler deals with the results of the background operation. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //if (e.Cancelled == true) //{ // resultLabel.Text = "Canceled!"; //} //else if (e.Error != null) //{ // resultLabel.Text = "Error: " + e.Error.Message; //} //else //{ // resultLabel.Text = "Done!"; //} } } public class ScriptTestManager : TestManager { protected Dictionary<string, string> m_FuncMap = new Dictionary<string, string>(); protected IScriptVM vm = null; public ScriptTestManager() { } public IScriptVM ScriptVM { get { return vm; } } public Dictionary<string, string> ScriptFuncName { get { return m_FuncMap; } } public virtual bool TM_InitVM(string name) { vm = CScriptVM.CreateVM(name); return null != vm; } public string DefaultScriptPath { get { return vm.DefaultScriptPath; } set { vm.DefaultScriptPath = value; } } public void SetLog(SimpleLogger log) { vm.Logger = log; } public override bool TM_Init() { if (!vm.VM_Init()) { return false; } return base.TM_Init(); } public override void Dispose() { } public virtual bool TM_Start(string sTestScript) { string path = Path.GetDirectoryName(sTestScript); vm.SearchPath.Add(path); if (!vm.VM_Renew()) { return false; } if (!vm.VM_LoadFile(sTestScript)) { return false; } return base.TM_Start(); } //public override bool TM_Stop() //{ // return true; //} public override ETestResult TestPlan(int nCurCycle, int dut) { if (!ScriptFuncName.ContainsKey("TestPlan")) return ETestResult.TR_Done; string sFuncName = ScriptFuncName["TestPlan"]; if (null != vm.VM_Find(sFuncName)) { object rawValue = vm.VM_Call(sFuncName, nCurCycle, dut); bool ret = false; try { ret = Convert.ToBoolean(rawValue); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } if (!ret) { return ETestResult.TR_End; } } return ETestResult.TR_Continue; } public override ETestResult OnTestBegin() { base.OnTestBegin(); if (!ScriptFuncName.ContainsKey("PrevTest")) return ETestResult.TR_Done; string sFuncName = ScriptFuncName["PrevTest"]; if (null != vm.VM_Find(sFuncName)) { object rawValue = vm.VM_Call(sFuncName); bool ret = false; try { ret = Convert.ToBoolean(rawValue); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } if (!ret) { return ETestResult.TR_End; } } return ETestResult.TR_Continue; } public override ETestResult OnTestEnd() { base.OnTestEnd(); if (!ScriptFuncName.ContainsKey("PostTest")) return ETestResult.TR_Done; string sFuncName = ScriptFuncName["PostTest"]; if (null != vm.VM_Find(sFuncName)) { object rawValue = vm.VM_Call(sFuncName); bool ret = false; try { ret = Convert.ToBoolean(rawValue); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } if (!ret) { return ETestResult.TR_End; } } return ETestResult.TR_End; } public override ETestResult OnModeBegin(TestMode tm) { if (!ScriptFuncName.ContainsKey("PrevTestMode")) return ETestResult.TR_Done; string sFuncName = ScriptFuncName["PrevTestMode"]; if (null != vm.VM_Find(sFuncName)) { object rawValue = vm.VM_Call(sFuncName, tm); bool ret = false; try { ret = Convert.ToBoolean(rawValue); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } if (!ret) { return ETestResult.TR_End; } } return ETestResult.TR_Continue; } public override ETestResult OnModeEnd(TestMode tm) { if (!ScriptFuncName.ContainsKey("PostTestMode")) return ETestResult.TR_Done; string sFuncName = ScriptFuncName["PostTestMode"]; if (null != vm.VM_Find(sFuncName)) { object rawValue = vm.VM_Call(sFuncName, tm); bool ret = false; try { ret = Convert.ToBoolean(rawValue); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } if (!ret) { return ETestResult.TR_End; } } return ETestResult.TR_Continue; } } public class ScriptEventModule { protected IScriptVM vm = null; public ScriptEventModule() { } public IScriptVM ScriptVM { get { return vm; } } public virtual bool Init(string name) { vm = CScriptVM.CreateVM(name); if (null != vm) { return true; } if (!vm.VM_Init()) { return false; } return true; } public string DefaultScriptPath { get { return vm.DefaultScriptPath; } set { vm.DefaultScriptPath = value; } } public void SetLog(SimpleLogger log) { vm.Logger = log; } public bool Reset() { if (!vm.VM_Renew()) { return false; } return true; } public void Dispose() { } public void LogException(Exception e) { if (null != vm) vm.VM_LogException(e); } public bool Load(string sTestScript) { if (!vm.VM_LoadFile(sTestScript)) { return false; } return true; } public object Call(string sFuncName, params object[] args) { if (null == vm.VM_Find(sFuncName)) return null; object r = null; try { r = vm.VM_Call(sFuncName, args); } catch (FormatException) { // Console.WriteLine("Bad Format"); } catch (InvalidCastException) { // Console.WriteLine("No Conversion"); } return r; } } }
最新发布
06-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值