今天在c#中跨线程访问窗口上的控件时,出现错误,网上找了一下: 使用BackgroundWorker组件(推荐使用这个方法)
BackgroundWorker是.NET里面用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。耗时的操作(如下载和数据库事务)。用法简单
private void button4_Click(object sender, EventArgs e) { using (BackgroundWorker bw = new BackgroundWorker()) { bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerAsync("Tank"); } } void bw_DoWork(object sender, DoWorkEventArgs e) { // 这里是后台线程, 是在另一个线程上完成的 // 这里是真正做事的工作线程 // 可以在这里做一些费时的,复杂的操作 Thread.Sleep(5000); e.Result = e.Argument + "工作线程完成"; } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了 this.label4.Text = e.Result.ToString(); }
代码来自:http://www.cnblogs.com/TankXiao/p/3348292.html
还找了一个串口通信的中使用invoke的例子
构造函数 InitializeComponent(); //为串口绑定接收数据事件 this.serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); //初始化下拉串口名称列表框 string[] ports = SerialPort.GetPortNames(); Array.Sort(ports); dotlist.Add(100); /* 串口设置 this.serialPort1.PortNum= comboBox1.Text.ToString(); //端口号 this.serialPort1.Parity= 0; //奇偶校验 this.serialPort1.BaudRate= 9600;//串口通信波特率 this.serialPort1.ByteSize= 8; //数据位 this.serialPort1.StopBits= 1;//停止位 this.serialPort1.ReadTimeout= 1000; //读超时 */ comboBaudName.Items.AddRange(ports); //如果只有一个串口则选中 if(comboBaudName.Items.Count==1) { comboBaudName.SelectedIndex = 0; } //默认波特率选9600 this.comboBaudRate.Items.AddRange(new object[] { "2400", "4800", "9600", "19200", "38400", "57600", "115200"}); if (ports.Length == 1) { //comboBaudName.SelectedIndex = 0; comboBaudRate.SelectedText = "9600"; } //打开或关闭串口 private void button8_Click(object sender, EventArgs e) { //根据当前串口对象,来判断操作 if(serialPort1.IsOpen) { //串口状态是open时,text是关闭 点击,则关闭串口 serialPort1.Close(); button8.Text = "打开"; } else { //串口状态是close时,text是打开 点击,则设置好端口,波特率后打开 if(comboBaudName.Text=="") { MessageBox.Show("无效的串口!"); return; } if(comboBaudRate.Text=="") { MessageBox.Show("请设置波特率!"); return; } serialPort1.PortName = comboBaudName.Text; serialPort1.BaudRate = int.Parse(comboBaudRate.Text); try { serialPort1.Open(); button8.Text = "关闭"; } catch(Exception e1) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了。 serialPort1 = new SerialPort(); //显示异常信息给客户。 MessageBox.Show(e1.Message); } } } //接收串口数据函数 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { int n = serialPort1.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致 byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据 received_count += n;//增加接收计数 serialPort1.Read(buf, 0, n); ;//读取缓冲数据 builder.Clear();//清除字符串构造器的内容 //因为要访问ui资源,所以需要使用invoke方式同步ui。 this.Invoke((EventHandler)(delegate { //直接按ASCII规则转换成字符串 builder.Append(Encoding.ASCII.GetString(buf)); //追加的形式添加到文本框末端,并滚动到最后。 textBox1.AppendText(builder.ToString()); })); SerialPort sp = (SerialPort)sender; string indata = sp.ReadExisting(); } //发送串口数据 private void SendStringData(string data) { if(serialPort1.IsOpen) { serialPort1.Write(data); } else { MessageBox.Show("串口没有打开"); } } //发送数据按钮 private void button10_Click(object sender, EventArgs e) { if(serialPort1.IsOpen) { SendStringData(this.textBox2.Text); } }
代码转自:http://blog.csdn.net/ruanjiayou/article/details/49154963#