一般在上位机界面的开发中,通常都需要在后台线程计算处理数据。然后在上位机显示,对于多任务处理,通常都是采用多线程的方法,这就要求必须采用线程间的通信。最简单的就是全局变量,等同是在共享数据,但这并不是最安全可靠的,同时对系统的开销大,还存在资源争夺的问题。无论采用何种框架,都无法直接在子工作线程中,直接对主线程(UI)进行数据更新。
常用分几种C#UI开发下的使用方法:
1、通过UI线程的SynchronizationContext的Post/Send方法,这种方法本质上是一条委托调用。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
int temp;
SynchronizationContext SyncContext = null;
public Form1()
{
InitializeComponent();
SyncContext = SynchronizationContext.Current;
}
const int cycleNum = 10;
static int cnt = 10;
private void button1_Click(object sender, EventArgs e)
{
Thread listen = new Thread(new ThreadStart(TimeCount));
listen.IsBackground = true;
listen.Start();
{
}
// myEvent.WaitOne();
}
private void TimeCount()
{
while (true)
{
Thread.Sleep(1000);
temp++;
if (temp > 1000) temp = 1000;
SyncContext .Post(Settext, temp.ToString());
}
}
private void Settext(object state)
{
this.textBox6.Text = state.ToString();
}
private void time_out(object sender, EventArgs e)
{
// textBox6.Text = textBox6.Text+temp.ToString();
}
}
}
2、通过UI控件的Invoke/BeginInvoke方法
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
int temp;
delegate void Update(string text);
public Form1()
{
InitializeComponent();
}
private void Settext(string text)
{
textBox1.Text = text;
}
private void button1_Click(object sender, EventArgs e)
{
Thread temp_event= new Thread(new ThreadStart(TimeCount));
temp_event.IsBackground = true;
temp_event.Start();
}
private void TimeCount()
{
while (true)
{
temp++;
if (temp > 1000) temp = 1000;
Thread.Sleep(100);
this.BeginInvoke(new Update(Settext), temp.ToString());
}
}
}
}
3、通过BackgroundWorker取代Thread执行异步操作
4、通过取消线程安全检查来避免"跨线程操作异常"