首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BeginInvoke错误

BeginInvoke错误
EN

Stack Overflow用户
提问于 2010-08-06 16:19:18
回答 1查看 290关注 0票数 2

嗨,

这个问题是我在this link提出的问题的续篇。

我写了一个应用程序来比较那里使用的方法和其他方法。在调试模式下运行应用程序时,我收到错误消息“在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke”。在方法UpdateCustDetails中的第一个BeginInvoke上。但是,在没有调试的情况下运行代码时,它不会给出任何运行时错误。有什么想法吗?

谢谢你,阿比。

以下是我的代码:

代码语言:javascript
复制
public delegate void UpdateLabelDelegate(Label lb, string text);
public delegate void loadCustomersDelegate();

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        loadCustomersDelegate del = new loadCustomersDelegate(UpdateCustDetails);
        IAsyncResult ar = del.BeginInvoke(null, null);

        while (!ar.IsCompleted)
        {
        }

    }

    public void updateLabel(Label lb, string text)
    {

        lb.Text = text;

    }

    public void UpdateCustDetails()
    {
        BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label1, "Test" });
        BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label2, "Test1234" });
        BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label3, "Test5678" });
        BeginInvoke(new UpdateLabelDelegate(updateLabel), new object[] { label4, "Test0000" });
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-08-06 16:44:18

首先,关于发布的代码结构,我想说几件事,这可能会有所帮助。

代码的作用是这样的:

  • Form1的构造函数中,异步调用一个方法(在不同的线程上)
  • 该方法异步调用四个单独的方法来更新label控件。调用被推回到UI线程(同时,我们在Form1的constructor)
  • The构造函数上所在的线程在继续

之前等待原始方法完成

在这段代码中有许多sillinesses:

  • 异步调用方法(以非阻塞方式),然后代码等待其完成。除非有令人信服的理由将这段代码放在后台线程上,否则为什么不直接同步调用该方法呢?这将使最终的行为保持不变,但使调试和读取代码在等待ar.IsCompletedwhile循环中进行,你会发现UI线程实际上非常忙碌-在那个空循环上敲击CPU,而不是闲置并让后台线程运行。我怀疑同步调用该方法会使performant.
  • Because UpdateCustDetails更多地使用BeginInvoke,它将发送四个异步调用并立即返回。这意味着-即使构造函数正在等待ar.IsCompleted -您也不能保证在构造函数完成时标签会被更新,因为对updateLabel的四个调用不会阻塞。
  • 实际上,因为Form.BeginInvoke会将执行返回到窗体的UI线程,所以您真正要做的是启动一个后台线程,将工作返回到创建它的线程。

所以简而言之:忽略错误,去掉所有看起来很聪明的线程,然后这样做:

代码语言:javascript
复制
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        UpdateCustDetails();
    }

    public void updateLabel(Label lb, string text)
    {
        lb.Text = text;
    }

    public void UpdateCustDetails()
    {
        updateLabel(label1, "Test");
        updateLabel(label2, "Test1234");
        updateLabel(label3, "Test5678");
        updateLabel(label4, "Test0000");
    }
}

您将获得相同的结果,具有更好的性能和更好的可读性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3422048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档