当前位置: 首页 > article >正文

Winform Invoke与BeginInvoke

BeginInvoke与Invoke

BeginInvoke与Invoke联系

Invoke和BeginInvoke方法由ISynchronizeInvoke接口提供,且都需要一个委托对象作为参数。主要用于子线程操作主线程UI的控件,修改控件属性等。

BeginInvoke与Invoke区别

  • Invoke同步运行,会等待代码运行完之后返回,线程会阻塞。
  • BeginInvoke异步运行,调用之后立即返回,不会等待修改控件代码执行完,不会阻塞。

BeginInvoke与Invoke使用场景

  • 若后台线程在更新UI界面且不需要等待,则应该使用BeginInvoke方法进行异步操作。
  • 若后台线程在更新UI界面并且需要等待,则应该使用Invoke方法进行同步操作。

BeginInvoke与Invoke软件中执行顺序

private Thread invokeThread;
private delegate void invokeDelegate();
private void StartMethod(){
   //C代码段......
   Control.Invoke(new invokeDelegate(invokeMethod));
  //D代码段......
}

private void invokeMethod(){
  //E代码段
}

private void butInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   invokeThread = new Thread(new ThreadStart(StartMethod));
   invokeThread.Start();
   //B代码段......
}

A——>(Start一开始B和StartMethod的C就同时执行)—->(C执行完了,不管B有没有执行 完,invokeThread把消息封送(invoke)给UI线程,然后自己等待)—->UI线程处理完butInvoke_Click消息后, 处理invokeThread封送过来的消息,执行invokeMethod方法,即代码段E,处理往后UI线程切换到invokeThread线程。

Task与Invoke和BeginInvoke之间的组合使用

       //主线程点击按键
       private  void button1_Click(object sender, EventArgs e)
       {
           //子线程
           Task.Run(() =>
           {
               for (int i = 0; i < 10; i++)
               {
                   t1++;
                   this.lblTask1.BeginInvoke(new MethodInvoker(() =>
                   {
                       lblTask1.Text = t1.ToString();
                       //在这里延时会阻塞主线程,导致界面卡顿,需要放在BeginInvoke外面
                       //Thread.Sleep(500);
                   }));
                   //在子线程延时等待,不阻塞主线程
                   Thread.Sleep(500);
               }
           });
       }

由于Invoke和BeginInvoke都是操作的主线程,所以尽量避免在子线程调用Invoke和BeginInvoke方法里再放其他延时操作,这样会导致界面卡顿的现象。

C#窗体子线程调用主线程控件方法

Winform中子线程调用主线程控件方法
 this.Invoke(new Action(() =>
 {
     //调用主线程控件
 }));
 this.BeginInvoke(new Action(() =>
 {
     //调用主线程控件
 }));
WPF中子线程调用主线程控件方法
Application.Current.Dispatcher.Invoke(((Action)delegate ()
{
    // 在主线程中执行需要操作的UI代码
}));
await Application.Current.Dispatcher.BeginInvoke(((Action)delegate ()
{
    // 在主线程中执行需要操作的UI代码
}));

参考:

C# Invoke和BeginInvoke-CSDN博客

C#及WPF多线程定义和使用2(Task)_wpf task-CSDN博客


http://www.kler.cn/a/404976.html

相关文章:

  • element-plus的组件数据配置化封装 - table
  • SpringBoot(8)-任务
  • Python深度学习环境配置(Pytorch、CUDA、cuDNN),包括Anaconda搭配Pycharm的环境搭建以及基础使用教程(保姆级教程,适合小白、深度学习零基础入门)
  • 音频信号采集前端电路分析
  • 什麼是ISP提供的公共IP地址?
  • 集合卡尔曼滤波(Ensemble Kalman Filter),用于二维滤波(模拟平面上的目标跟踪),MATLAB代码
  • Java阶段三04
  • Java集合ConcurrentHashMap——针对实习面试
  • 微服务架构:10个实用设计模式
  • springboot基于微信小程序的旧衣回收系统的设计与实现
  • Web中间件漏洞总结——IIS篇
  • 【K8S系列】Kubernetes 中如何调试imagePullSecrets配置详细步骤介绍
  • Unity图形学之灯光的原理
  • LeetCode131:分割回文串
  • STM32芯片EXIT外部中断的配置与原理以及模板代码(标准库)
  • C语言-11-18笔记
  • 利用开源的低代码表单设计器FcDesigner高效管理和渲染复杂表单结构
  • 网络层8——IP多播
  • 论文复现_How Machine Learning Is Solving the Binary Function Similarity Problem
  • mapStruct详解
  • docker部署redis7
  • 说一说JS伪数组和数组的区别?
  • 云原生基础-云计算概览
  • 算法-二分查找2(代码笔记)
  • 在 Ubuntu 上配置防火墙以开放特定端口
  • 【Redis_Day5】String类型