千家信息网

.NET跨线程控件的相关操作是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,.NET跨线程控件的相关操作是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在.NET中,如果我们在非UI线程上访问窗体上的控件
千家信息网最后更新 2026年11月01日.NET跨线程控件的相关操作是什么

.NET跨线程控件的相关操作是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在.NET中,如果我们在非UI线程上访问窗体上的控件的时候,会产生一个跨线程调用的异常,那么如何处理这种情况呢?我介绍了使用Control.Invoke方法,如果你不习惯使用委托,那么.Net还为我们提供了一个组件BackgroundWorker,你可以使用这个组件,以事件的方式去处理这种跨线程的控件访问。下面我就来详细的介绍一下这个组件的用法。

我们先来看一下BackgroundWorker提供了哪些常用的成员,

事件

◆DoWork:我们在这个事件中,执行需要异步处理的工作。

◆ProgressChanged:我们在这个事件中,接收并处理异步处理过程中的信息。

◆RunWorkerCompleted:我们在这个事件中,执行异步处理结束的工作。

方法

◆RunWorkerAsync()和RunWorkerAsync(object argument):这两个方法触发DoWork事件,开始异步操作。

◆ReportProgress(int percentProgress)和ReportProgress(int percentProgress, object userState):这两个方法触发ProgressChanged事件。

◆CancelAsync:结束后台的异步操作。

属性

◆bool CancellationPending:指示当前的后台的异步操作是否正在被取消,执行CancelAsync方法会导致这个属性为true。

◆bool IsBusy:指示当前的后台异步操作是否正在进行,进行中为true。

◆bool WorkerReportsProgress:获取或设置当前的BackgroundWorker是否可以执行ProgressChanged方法。

◆bool WorkerSupportsCancellation:获取或设置当前的BackgroundWorker是否可以执行CancelAsync方法。

OK,有了上面这些成员,我们来看一下BackgroundWorker是如何工作的。

Step 1. 当然是定义一个BackgroundWorker的实例,你可以从工具箱中拖拽一个BackgroundWorker控件到窗体上或者在代码中直接声明;

Step 2. 生成DoWork事件并在DoWork事件的中添加需要异步执行的代码。在异步执行的代码中,如果需要处理界面中的控件,请调用ReportProgress方法,而不要直接处理(例如给控件赋值),因为DoWork事件跟正常的界面的事件不同,这个事件在非UI线程上执行,所以才能异步执行。

Step 3. 生成ProgressChanged事件并添加控件处理的代码,因为这个事件是在UI线程上执行的,所以可以给界面中的控件进行赋值等操作。

Step 4. 如果需要,请生成RunWorkerCompleted事件,在此处理异步执行结束的业务逻辑。当然,此事件也是在UI线程上执行的,可以给界面中的控件进行赋值等操作。

Step 5. 在需要执行异步操作的地方调用RunWorkerAsync方法,开始执行异步调用。

下面是具体的代码:

public Form1()      {        InitializeComponent();         bWorker.DoWork += new DoWorkEventHandler(bWorker_DoWork);         bWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bWorker_RunWorkerCompleted);        bWorker.ProgressChanged += new ProgressChangedEventHandler(bWorker_ProgressChanged);        this.Text = "UI thread id is:" + Thread.CurrentThread.ManagedThreadId.ToString();      }     BackgroundWorker bWorker = new BackgroundWorker();    void bWorker_DoWork(object sender, DoWorkEventArgs e)     {     int tick = (int)e.Argument;      Thread thr = Thread.CurrentThread;     for (int i = 0; i < 30; i++)      {        if (bWorker.CancellationPending)         {            e.Cancel = true;              //break;       }     else        {               Thread.Sleep(TimeSpan.FromSeconds(tick));              bWorker.ReportProgress(i, DateTime.Now.ToString() + "\\TID:" + thr.ManagedThreadId.ToString());          }        }            }   void bWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)     {    progressBar1.Value = e.ProgressPercentage;       label1.Text = e.UserState.ToString();    }    void bWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)   {     label1.Text = DateTime.Now.ToString();        progressBar1.Value = progressBar1.Maximum;         if (e.Cancelled)     label1.Text = "User cancelled.";    }    private void btnInvoke_Click(object sender, EventArgs e)   {     bWorker.WorkerReportsProgress = true;       bWorker.WorkerSupportsCancellation = true;        if (!bWorker.IsBusy)        bWorker.RunWorkerAsync(1);    }   private void btnCancel_Click(object sender, EventArgs e)     {        if (bWorker.WorkerSupportsCancellation)           bWorker.CancelAsync();    }

上面的代码请注意几个地方:

1. 第50行,开始调用RunWorkerAsync方法前,请先判断IsBusy属性是否是false,因为如果为true,则说明上一次的调用还没有结束,再次调用会引发异常。

2. 第56行,调用CancelAsync方法前,请先设置WorkerSupportsCancellation属性为true,否则会引发异常。

3. 第26行,调用ReportProgress方法前,请先设置WorkerReportsProgress属性为true,否则会引发异常。

4. RunWorkerAsync方法传递的参数是object类型,这个参数的值可以在DoWork事件的参数e中的属性Argument获得。

5. ReportProgress方法传递的参数可以在事件ProgressChanged中的参数e中获得。

6. 调用CancelAsync方法只是向后台的异步线程发出结束申请,具体什么时候结束,由线程自动管理。

7. 在RunWorkerCompleted事件中,如果想知道后台任务是正常执行完毕还是被调用CancelAsync方法强制中断,请参考事件的参数e的Cancelled属性。(奇怪的是这个属性不会在你调用CancelAsync方法后自动设置为true,你需要象代码中的20行那样进行设置。)

8. 请注意第7行和第26行的代码,这两段代码中的线程的ID,说明了DoWork事件和UI是在两个不同的线程上执行。

实际上BackgroundWorker并非直接用来解决跨线程的控件调用的问题,只是它提供了一种工作机制,可以让你的程序利用它来执行异步调用,并且在异步调用的过程中进行控件的操作。

关于.NET跨线程控件的相关操作是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

事件 方法 线程 控件 代码 处理 属性 参数 后台 界面 问题 工作 两个 是在 组件 生成 不同 只是 地方 成员 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 瑰夏咖啡 互联网科技工作委员会 互联网科技工作委员会主任 互联网巨头反垄断金融科技 美国互联网科技巨头监管 无线互联网科技 联恩商钥互联网科技有限公司 互联网科技股午盘股票涨跌 华脉科技工业互联网产品 深圳互联网科技怎么样 汉立互联网科技有限公司联系电话 开启互联网科技时代小说 湖南一路畅行互联网科技 深圳育鹏互联网科技有限公司招聘 互联网新科技动漫ppt素材 西安小鹰速贷互联网科技有限公司 21世纪互联网科技成就 领航科技大厦互联网公司 银川新华互联网科技学校原画 安徽零酒互联网科技有限公司 互联网科技巨头监管 北京互联网科技 互联网科技小贷 互联网科技公司怎么样 火传媒上海互联网科技 华脉科技工业互联网产品 青岛中康互联网医疗科技有限公司 全球顶尖互联网科技公司 福仕德教育科技互联网 科技信息时代互联网发展
0