eventhandler begininvoke(C#中窗体控件, 我要实现下面的功能:这边通过接口读取信号,将信号的内容写到textBox里面 ,)

本文目录
- C#中窗体控件, 我要实现下面的功能:这边通过接口读取信号,将信号的内容写到textBox里面 ,
- C#多线程 我要如何实现1秒执行一次A区代码 然后执行B区 然后在回去A 这样循环
- C#在其它类的线程工更新winForm中的textbox内容
- C# 多线程方法 控制两个进度条
C#中窗体控件, 我要实现下面的功能:这边通过接口读取信号,将信号的内容写到textBox里面 ,
public partial class Form1 : Form
{
Timer t = new Timer();
Timer t2 = new Timer();
public Form1()
{
InitializeComponent();
t.Interval = 1000;
t.Tick += new EventHandler(t_Tick);
t.Start();
t2.Interval = 500;
t2.Tick += new EventHandler(t2_Tick);
t2.Start();
}
// 模拟接口取得数据
void t_Tick(object sender, EventArgs e)
{
textBox1.BeginInvoke(new Action(() =》 {
textBox1.Text = Guid.NewGuid().ToString();
}));
}
// 模拟闪烁
void t2_Tick(object sender, EventArgs e)
{
textBox1.BeginInvoke(new Action(() =》
{
string str = textBox1.Text;
textBox1.Text = "";
textBox1.Text = str;
}));
}
}
C#多线程 我要如何实现1秒执行一次A区代码 然后执行B区 然后在回去A 这样循环
编写桌面程序的时候当遇到长时间的方法调用时,大家都会遇到主线程被挂起、界面无响应的状况。线程操作是解决类似问题的绝佳手段,但对于刚接触线程的朋友来讲编写和调试多线程程序是非常痛苦的,尤其是在VC的MFC下,没有一定的C++基础,很难做出专业的多线程程序来。
幸好,.Net框架为我们提供了非常简便的方法和机制来创建多线程程序,譬如:Thread、线程池、异步方法调用以及BackgroundWorker!Thread和BackgroundWorker在MSDN中关于这两个类都有非常详细的解释以及丰富的示例,在后续的文章里我们会利用非常实际的示例程序来进行实战。在这里我们首先讨论异步方法调用。
所谓异步方法调用英文即为Asynchronous Method Invocation,讨论异步方法调用实际上就是讨论如何以非阻塞的方式来调用方法。常规的阻塞式方法调用例如:
//调用同一个耗时的方法
private void a()
{
Thread.Sleep(10000);
}
//阻塞式调用
private void button1_Click(object sender, EventArgs e)
{
a();
MessageBox.Show("button1_Click will return!");
}
当单击button1后,主界面立即失去响应,持续10s后会显示一个消息框报告button1_Click方法将要返回,这时a()方法已经调用结束并返回。这表明主线程是在按照button1_click-》a()-》button1_click的顺序依次执行代码,所有代码都在主线程中执行。
然后,我们在窗体上放置第二个button,即button2,来演示如何进行异步方法调用。.Net2.0提供了两种途径实现异步方法调用,每种途径实际上都是使用委托来实现。一种是简单的无参数传递的MethodInvoker委托类型,另一种是标准的delegate类型。MethodInvoker类型的委托不接受任何参数传递,而delegate类型的委托使用起来则相当灵活,并且可以传递任意类型的参数。我们主要以MethodInvoker为例,首先看一下button2_Click事件的内容:
//调用同一个耗时的方法
private void a()
{
Thread.Sleep(10000);
}
//异步方法调用
private MethodInvoker simpleDelegate1;
private void button2_Click(object sender, EventArgs e)
{
simpleDelegate1 = new MethodInvoker(a);
simpleDelegate1.BeginInvoke(null, null);
MessageBox.Show("button2_Click will return!");
}
当单击button2后,会立即显示一个消息框报告button1_Click方法将要返回,而主界面没有失去响应。这表明在主线程下的button2_click要返回了!而这时的a()方法正在另一个独立的线程上继续执行着,而且在执行的10s过程中,我们仍然可以随意拖动窗体、改变窗体大小、继续单击窗体上的按钮甚至关闭窗体。这种调用即称为异步方法调用。
使用c++的朋友都知道函数指针,其实.Net下的委托就是一个函数指针类型,在.Net下已经没有函数的概念了,所以也称为方法指针,只不过框架把一些东西隐藏了,我们不必关心细节,不必用指针的方式显示声明罢了。其实委托也可以同步阻塞的方式执行,你可以尝试将button2_Click中的代码:
simpleDelegate1.BeginInvoke(null, null);
更改为:
simpleDelegate1.Invoke();
其执行方式与button1_Click完全一样。
Invoke以同步方式开始执行委托,其参数必须与要执行的方法完全一致。BeginInvoke就是以异步方式开始执行委托,它与您需要执行的方法具有相同的参数,另外还有两个可选参数。在.Net下当你看到以Begin开头的方法时几乎都是以异步方式执行代码。而对应BeginInvoke的就是EndInvoke方法,EndInvoke的任务就是传递BeginInvoke的返回值,我们将在下一篇博文中详细介绍BeginInvoke和EndInvoke的使用,以及如何捕获异步方法调用的结束。
C#在其它类的线程工更新winForm中的textbox内容
首先你应该把Mainform里的TextBox对象(假设叫做textBox1)保存在TCPServer.Instance里;其次由于是后台线程,所以不能直接对textBox1的text赋值,应该这样:
void listenerProc()
{
while (true)
{
textBox1.Invoke( new EventHandler( delegate{ textBox1.Text = "xxxxx"; } ) );
}
}
C# 多线程方法 控制两个进度条
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Demo0004
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//线程开始的时候调用的委托
private delegate void maxValueDelegate(int maxValue);
//线程执行中调用的委托
private delegate void nowValueDelegate(int nowValue);
private void button1_Click(object sender, EventArgs e)
{
ThreadMethod method = new ThreadMethod();
//先订阅一下事件
method.threadStartEvent += new EventHandler(method_threadStartEvent);
method.threadEvent += new EventHandler(method_threadEvent);
method.threadEndEvent += new EventHandler(method_threadEndEvent);
Thread thread = new Thread(new ThreadStart(method.runMethod));
thread.Start();
}
/// 《summary》
/// 线程开始事件,设置进度条最大值
/// 但是我不能直接操作进度条,需要一个委托来替我完成
/// 《/summary》
/// 《param name="sender"》ThreadMethod函数中传过来的最大值《/param》
/// 《param name="e"》《/param》
void method_threadStartEvent(object sender, EventArgs e)
{
int maxValue = Convert.ToInt32(sender);
maxValueDelegate max = new maxValueDelegate(setMax);
this.Invoke(max, maxValue);
}
/// 《summary》
/// 线程执行中的事件,设置进度条当前进度
/// 但是我不能直接操作进度条,需要一个委托来替我完成
/// 《/summary》
/// 《param name="sender"》ThreadMethod函数中传过来的当前值《/param》
/// 《param name="e"》《/param》
void method_threadEvent(object sender, EventArgs e)
{
int nowValue = Convert.ToInt32(sender);
nowValueDelegate now = new nowValueDelegate(setNow);
this.Invoke(now, nowValue);
}
/// 《summary》
/// 线程完成事件
/// 《/summary》
/// 《param name="sender"》《/param》
/// 《param name="e"》《/param》
void method_threadEndEvent(object sender, EventArgs e)
{
MessageBox.Show("执行已经完成!");
}
/// 《summary》
/// 我被委托调用,专门设置进度条最大值的
/// 《/summary》
/// 《param name="maxValue"》《/param》
private void setMax(int maxValue)
{
this.progressBar1.Maximum = maxValue;
}
/// 《summary》
/// 我被委托调用,专门设置进度条当前值的
/// 《/summary》
/// 《param name="nowValue"》《/param》
private void setNow(int nowValue)
{
this.progressBar1.Value = nowValue;
}
}
public class ThreadMethod
{
/// 《summary》
/// 线程开始事件
/// 《/summary》
public event EventHandler threadStartEvent;
/// 《summary》
/// 线程执行时事件
/// 《/summary》
public event EventHandler threadEvent;
/// 《summary》
/// 线程结束事件
/// 《/summary》
public event EventHandler threadEndEvent;
public void runMethod()
{
int count = 100; //执行多少次
threadStartEvent.Invoke(count, new EventArgs());//通知主界面,我开始了,count用来设置进度条的最大值
for (int i = 0; i 《 count; i++)
{
Thread.Sleep(100);//休息100毫秒,模拟执行大数据量操作
threadEvent.Invoke(i, new EventArgs());//通知主界面我正在执行,i表示进度条当前进度
}
threadEndEvent.Invoke(new object(), new EventArgs());//通知主界面我已经完成了
}
}

更多文章:
全球新冠肺炎疫情背景下航运发展(盐田港复苏日志:半年历劫从“低谷”到“爆仓” 疫情之后巨轮如何越洋航行)
2026年9月7日 17:10
matlab求解带字母参数方程组(我想matlab求一个关于x,y的方程组 ab c d f e h m n 都是参数)
2026年9月7日 16:30
oracle中的循环语句(下面哪个不是oracle程序设计中的循环语句 a for)
2026年9月7日 15:30
电脑里2个系统怎么删除一个(电脑开机显示有两个系统,如何删除一个)
2026年9月7日 12:20
scrollthrough意思(“scroll”是什么意思)
2026年9月7日 08:00
怎么激活keygen(注册机如何激活cad2008一个简单激活cad2008的方法)
2026年9月7日 06:30
vba编写excel插件(excel vba中能否动态创建控件)
2026年9月7日 04:40





