嗨,
这个问题是我在this link提出的问题的续篇。
我写了一个应用程序来比较那里使用的方法和其他方法。在调试模式下运行应用程序时,我收到错误消息“在创建窗口句柄之前,无法在控件上调用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" });
}
}发布于 2010-08-06 16:44:18
首先,关于发布的代码结构,我想说几件事,这可能会有所帮助。
代码的作用是这样的:
Form1的构造函数中,异步调用一个方法(在不同的线程上)之前等待原始方法完成
在这段代码中有许多sillinesses:
ar.IsCompleted的while循环中进行,你会发现UI线程实际上非常忙碌-在那个空循环上敲击CPU,而不是闲置并让后台线程运行。我怀疑同步调用该方法会使performant.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");
}
}您将获得相同的结果,具有更好的性能和更好的可读性。
https://stackoverflow.com/questions/3422048
复制相似问题