我正在使用它从另一个线程更新主线程中的控件:
private void ShowHourGlassSafe(bool visible)
{
this.Invoke((EventHandler)((s, ev) => pictureBoxHourGlass.Visible = visible));
}
我想知道这样做会带来什么影响,或者是否有任何风险会失败?
从很多例子来看,我找不到像这样的东西。
可能是因为它完全错了?
答案 0 :(得分:3)
嗯,你已经选择了一个相当奇怪的代表来选择,因为你已经选择了一个有两个参数的代表,尽管事实上既不需要也不会提供。我不知道这是否会导致它破裂,但它肯定无济于事。您最有可能使用不带参数的委托并且不返回任何值,例如:
private void ShowHourGlassSafe(bool visible)
{
this.Invoke((MethodInvoker)(() => pictureBoxHourGlass.Visible = visible));
}
除此之外,你所做的基本概念非常好。
答案 1 :(得分:2)
此类代码存在典型问题:
如果UI线程正在做一些不明智的事情,比如等待线程完成,你就会死锁。使用Invoke是没有意义的,它阻止工作线程没有任何好处,只需使用BeginInvoke。解决死锁潜力和不必要的延迟。
关闭用户界面并处理pictureBoxHourGlass后,您将崩溃。在允许UI关闭之前确保线程不再运行通常被忽视。仅显示小时玻璃是不够的,您还必须采取对策以防止用户关闭UI。或以其他方式将其与首先取消线程的方式联系起来
当一小时玻璃出现时,用户通常会被迷惑,而他没有做任何事情要求完成任务。 99%正确的情况是你在UI线程中显示带有代码的沙漏,然后启动线程。并在线程完成时再次隐藏它。使用BackgroundWorker或Task类最容易,它们可以在作业完成后在UI线程上运行代码。
支持Action委托类型以保持一致性:
private void ShowHourGlassSafe(bool visible) {
this.BeginInvoke(new Action(() => something.Visible = visible));
}