1. Invoke and BeginInvoke
control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。
使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。
使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。
.net freamwork3.5 之后 可以用action封装匿名方法。
this.Invoke(new Action()=>
{
要执行的代码;
});
2. SynchronizationContext
SynchronizationContext在通讯中充当传输者的角色,实现功能就是一个线程和另外一个线程的通讯。
Send() 是简单的在当前线程上去调用委托来实现(同步调用)。也就是在子线程上直接调用UI线程执行,等UI线程执行完成后子线程才继续执行。
Post() 是在线程池上去调用委托来实现(异步调用)。这是子线程会从线程池中找一个线程去调UI线程,子线程不等待UI线程的完成而直接执行自己下面的代码。
例子:
private SynchronizationContext mainThreadSynContext;
public UdpServer(int port)
{
udpServer = new UdpClient(port);
ipEndPoint = new IPEndPoint(IPAddress.Any, port);
udpServer.Client.Blocking = false;//设置为非阻塞模式
mainThreadSynContext = SynchronizationContext.Current;//在这里记录主线程的上下文
/// 网络数据接收线程
Thread th = new Thread(Receive);
// th.IsBackground = true;
th.IsBackground = true;
th.Start();
}
void Receive()
{
byte[] recBuffer;
//远端IP
IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
recBuffer = udpServer.Receive(ref remotePoint);
if (recBuffer != null)
{
int dataLength = recBuffer[4] * 256 + recBuffer[5];
if (recBuffer.Length == 24)
{
HeartBeat heartBeat = getYFRadar.GetHeart(recBuffer);
mainThreadSynContext.Post(new SendOrPostCallback(GetRadarAz), heartBeat.ToString());
// Form1.form1.DrawFixJammerDirctGD(heartBeat);
}
}
}
}
catch (Exception e)
{
string.Format(e.ToString());
}
public void GetRadarAz(object o)
{
double az = Convert.ToDouble(o.ToString());
Form1.form1.DrawFixJammerDirctGD(az);
}