加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 从另一个类和线程的接口回调更新winform

发布时间:2020-12-15 22:12:20 所属栏目:百科 来源:网络整理
导读:我有一个winform和一个连续发送更新的接口回调.我希望能够从回调接口更新label1.Text.然而,因为inface在一个单独的线程上运行,我不认为我可以直接执行它所以我试图使用委托并调用. 但是我遇到了一个错误: 在创建窗口句柄之前,无法在控件上调用Invoke或Begin
我有一个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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读