最近在弄c#调用c++接口,通过回调函数上传数据,在c#界面显示。由于该接口为同步(阻塞),回调部分会卡住界面,只有全部数据加载完了才会显示出来。这里通过子线程的方法来操作主界面,让主界面显示出来后,数据一条条显示。
外部调用接口:
public void SelfAutoDetect()
{
Thread thread = new Thread(BeginDetect);
thread.Start();
}
private void BeginDetect()
{
IBGISequence.SelfDetectCb callback = new IBGISequence.SelfDetectCb(CallbackFunc);
IBGISequence.Seq_AutoSelfDetect(callback);
}
方法1,Invoke和BeginInvoke方法
前者为同步,后者为异步,所以采用后者。
委托:
public delegate void UpdateData(string name, int result);
public event UpdateData updateData;
事件:
this.updateData += SelfDetectCtrl_updateData;
实现:
private void CallbackFunc(IntPtr devname, int result)
{
// 异步刷新ui
BeginInvoke(updateData, new object[] { Marshal.PtrToStringAuto(devname), result });
}
void SelfDetectCtrl_updateData(string name, int result)
{
// 操作ui控件,如listview等
}
方法2:WindowsFormsSynchronizationContext
有Post(异步)和Send(同步)方法,采用Post
定义:
private WindowsFormsSynchronizationContext sync = WindowsFormsSynchronizationContext.Current as WindowsFormsSynchronizationContext;// 线程间异步对象
使用:
private void CallbackFunc(IntPtr devname, int result)
{
// 异步刷新ui
sync.Post(Func, object obj);
}
void Func(object obj)
{
// 操作ui控件,如listview等,将obj转换为相应的对象,如int a = obj as int;
}
总结:
这两种方法都提供了子线程操作ui,方法类似,不同之处在于方法1可以传递多个参数,方法2只能传递1个参数(可以定义一个类,将参数包装到类中)。