我有一个winform和一个连续发送更新的接口回调.我希望能够从回调接口更新label1.Text.然而,因为inface在一个单独的线程上运行,我不认为我可以直接执行它所以我试图使用委托并调用.
在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke – at
form1.Invoke(form1.myDelegate,new Object[] { so.getString() });
这是完整的代码.
public partial class Form1 : Form { MyCallBack callback; public delegate void UpdateDelegate(string myString); public UpdateDelegate myDelegate; public Form1() { InitializeComponent(); myDelegate = new UpdateDelegate(UpdateDelegateMethod); callback = new MyCallBack(this); CallBackInterfaceClass.SetCallBack(callback); callback.OnUpdate(); } public void UpdateDelegateMethod (String str) { label1.Text = str; } } class MyTestCallBack : Callback { public Form1 form1; public SomeObject so; public MyTestCallBack(Form1 form) { this.form1 = form; } public void OnUpdate(SomeObject someobj) { so = someobj; OnUpdate(); } public void OnUpdate() { form1.Invoke(form1.myDelegate,new Object[] { so.getString() }); } }
两个问题.
>谁能解释我做错了什么?
>这实际上是最好的方法吗?
以下是基于bokibeg的回复(见下文)的答案,并进行了一些修改以使其工作:
06002
解决方法
这是我要做的:
public partial class Form1 : Form { MyTestCallBack _callback; public Form1() { InitializeComponent(); _callback = new MyTestCallBack(); _callback.MyTestCallBackEvent += callback_MyTestCallBackEvent; _callback.OnUpdate(); } private callback_MyTestCallBackEvent(MyTestCallBackEventArgs e) { // Todo: Invoke code here with e.g. label1.Text = e.someObj.ToString()... } } class MyTestCallBackEventArgs : EventArgs { public SomeObject SomeObj { get; set; } } class MyTestCallBack : Callback { public event EventHandler<MyTestCallBackEventArgs> MyTestCallBackEvent; private SomeObject _so; public MyTestCallBack() { // } protected virtual void OnMyTestCallBackEvent(MyTestCallBackEventArgs e) { if (MyTestCallBackEvent != null) MyTestCallBackEvent(e); } public void OnUpdate(SomeObject someobj) { _so = someobj; OnMyTestCallBackEvent(new MyTestCallBackEventArgs { SomeObject = _so }); } }
它将GUI逻辑与线程正在执行的操作分开.它会触发一个事件,并且Form有责任随心所欲地做任何事情.
我不确定这是否编译,我在文本垫中写道.如果您有疑问,请告诉我.
你可能刚刚了解了代理并被它带走了,这类似于它使用一个事件,但事件被正确放置在“后端”逻辑中 – 表单可能会也可能不会使用它.还要注意form的代码是如何更好的,它没有那么多的样板代码只是为了实现一些后台服务类.
但请注意,即使在关闭表单后,MyTestCallBackEvent事件也可能继续触发,因此请确保在表单关闭或处理时取消订阅(或者当您觉得表单不再需要它时).
哦,我差点忘了:你得到的原始错误是因为你在不需要一个时调用了Invoke而且Form肯定还没准备好.阅读此问题以查看how to safely invoke controls.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。