gpt4 book ai didi

c# - 开始调用错误

转载 作者:太空宇宙 更新时间:2023-11-03 14:27:49 24 4
gpt4 key购买 nike

你好,

这个问题是我在 this link 上的问题的延续.

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

谢谢,阿比。

下面是我的代码:-

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" });
}
}

最佳答案

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

代码的作用是这样的:

  • Form1 的构造函数中, 异步调用一个方法(在不同的线程上)
  • 该方法异步调用四个单独的方法来更新标签控件。调用被推回到 UI 线程(我们在 Form1 的构造函数中所在的线程)
  • 与此同时,构造函数在继续之前等待原始方法完成

这段代码中有很多愚蠢的地方:

  • 异步调用方法(以非阻塞方式),然后代码等待其完成。除非有令人信服的理由让此代码位于后台线程上,否则为什么不直接调用同步方法呢?它将使最终行为保持不变,但会使调试和阅读代码变得更加容易。
  • 因为 while循环等待 ar.IsCompleted ,您会发现 UI 线程实际上非常忙 - 在那个空循环上敲打 CPU,而不是闲置并允许后台线程运行。我怀疑同步调用该方法的性能会更高。
  • 因为UpdateCustDetails使用 BeginInvoke ,它将发送四个异步调用并立即返回。这意味着 - 即使构造函数正在等待 ar.IsCompleted - 你不能保证标签会在构造函数完成时更新 - 因为对 updateLabel 的四次调用没有阻塞。
  • 事实上,因为Form.BeginInvoke将执行踢回窗体的 UI 线程,您真正在做的是启动后台线程,只是为了将工作踢回创建它的线程。

简而言之:忽略错误,取出所有看起来很聪明的线程内容,然后执行以下操作:

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");
}
}

您将获得相同的结果,但性能更好,代码更易读。

关于c# - 开始调用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3422048/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com