当前位置:网站首页>C#【委托/事件篇】跨线程访问窗体控件的方法
C#【委托/事件篇】跨线程访问窗体控件的方法
2022-08-10 03:43:00 【明如正午】
文章目录
一、直接调用方法,方法中使用委托【textBox1.InvokeRequired】
using System;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Thread th = null;
private void button1_Click(object sender, EventArgs e)
{
th = new Thread(Start);
th.IsBackground = true;
th.Start();
}
private void Start()
{
AddStr("111");
UpdateText4("222");
if (th != null)
{
th.Abort();
}
}
//方法一:TextBox1的委托
delegate void AddDg(string str); //声明一个委托
private void AddStr(string str)
{
if (textBox1.InvokeRequired)
{
AddDg dg = new AddDg(AddStr);
textBox1.Invoke(dg, str);
}
else
{
textBox1.Text += str;
}
}
//方法二:TextBox2的委托
private void UpdateText4(object str)
{
if (textBox2.InvokeRequired)
{
// 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
Action<string> actionDelegate = (x) => {
this.textBox2.Text += x.ToString(); }; //Lambda表达式的应用
//Action<string> actionDelegate = delegate (string txt) { this.textBox3.Text += txt; }; // 或者
this.textBox2.Invoke(actionDelegate, str);
}
else
{
this.textBox2.Text += str.ToString();
}
}
}
}
二、调用委托,委托进一步关联方法
1.使用委托【最基础的调用方法:委托五步法】
委托五步法:创建委托、声明委托、创建委托方法、委托绑定、调用委托
using System;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
//【01】声明委托
public delegate void SetFormTextDelegate();
//【02】创建委托对象
private SetFormTextDelegate SetFormText;
//【03】委托关联的方法
private void ExcuteMethod()
{
textBox1.Text = "跨线程调用控件成功";
}
public Form1()
{
InitializeComponent();
//【04】委托绑定
this.SetFormText = ExcuteMethod;
}
public Thread th = null;
private void button1_Click(object sender, EventArgs e)
{
th = new Thread(Start);
th.IsBackground = true;
th.Start();
}
private void Start()
{
//错误调用委托【报错:System.InvalidOperationException:“线程间操作无效: 从不是创建控件“Form1”的线程访问它。”】
//因为想要在多线程里操作主线程的控件,你还得经过控件的同意【使用.Invoke()方法】
//SetFormText();
//【05】正确调用委托
this.Invoke(SetFormText);
}
}
}
控件的父类Control提供了下边的方法:
2.使用Action作为委托来创建
微软从某个版本开始,出来了Action和Lamda表达式,Action是系统委托,也就是说,不需要我们手动创建委托了,它有个兄弟叫Func。
Action没有返回值,最多可以有16个参数。
Func必须要有返回值,最多可以有16个参数,最后一个参数表示返回值。
1)第一步简化:用Action作为委托来创建
/// <summary>
/// 多线程方法
/// </summary>
private void Start()
{
//【01】创建委托、绑定委托
Action action = new Action(ExcuteMethod);
//【02】调用委托
this.Invoke(action);
}
//委托关联的方法
private void ExcuteMethod()
{
textBox1.Text = "跨线程调用控件成功";
}
2)第二步简化:委托对象只用一次,所以可以直接放到参数里
/// <summary>
/// 多线程方法
/// </summary>
private void Start()
{
//【01】创建委托、绑定委托、调用委托
this.Invoke(new Action(ExcuteMethod));
}
//委托关联的方法
private void ExcuteMethod()
{
textBox1.Text = "跨线程调用控件成功";
}
3)第三步简化:用Lamda表达式代替方法【推荐使用!!!】
/// <summary>
/// 多线程方法
/// </summary>
private void Start()
{
//【01】创建委托、绑定委托、调用委托
this.Invoke(new Action(()=>
{
textBox1.Text = "跨线程调用控件成功";
}));
}
边栏推荐
- 1413.Minimum Value to Get Positive Step by Step Sum
- Redis 定长队列的探索和实践
- TCP协议之《ACK pingpong交互模式详解》
- 自定义训练,使用Generator dataset迭代数据报错
- 【网络迁移】Pytorch中的torch.no_grad对应MindSpore哪个方法
- maya视图如何切换
- goland json.Marshal导致&变成\u0026
- 测试常见问题100类(1)
- 什么是Jmeter?Jmeter使用的原理步骤是什么?
- The so-called software testing ability is actually these 5 points
猜你喜欢
MindSpore官方RandomChoiceWithMask算子用例报错
最牛最全的 Postman 实现 API 自动化测试教程
How to quickly become a software test engineer?What skills do testers need for a monthly salary of 15k?
【IO复用】poll
Embedded Sharing Collection 32
mindspore gpu版本安装问题
Did not detect default resource location for test class xxxx
Dynamic Web Development Fundamentals
【mindspore产品】【8卡分布式训练】davinci_model : load task fail, return ret
Do you know these basic types of software testing?
随机推荐
2022年P气瓶充装操作证考试题库及模拟考试
线程和线程间通信(C语言)
关于JWT 和Token(转)
线程执行测试效果
ZZULIOJ:1015: 计算时间间隔
goland console shows overlapping problem solution
goland json.Marshal导致&变成\u0026
day17正则表达式作业
Embedded Sharing Collection 32
TCP协议之《ACK pingpong交互模式详解》
2022年危险化学品经营单位主要负责人题库及模拟考试
ES高亮显示语法
sql优化
Dijkstra求最短路
c语言:通讯录(动态版本)
Dynamic Web Development Fundamentals
TCP协议之《ACK报文限速》
【网络迁移】Pytorch中的torch.no_grad对应MindSpore哪个方法
TCP协议之《对端MSS值估算》
互联网家装驶入深水区:谁在求变,又有谁在裸泳?