我看到有很多关于线程修改表单中的项目的问题; 但是,我只是想从一个线程中读取一个复选框的状态(例如)。所以......
是否有任何额外的开销来访问表单中的复选框的“已检查”状态(来自线程)-vs-创建将反映该复选框状态的bool,并让线程访问布尔值而不是?
答案 0 :(得分:3)
我建议将值存储在bool
字段中,而不管线程问题如何; CheckBox
应该是数据的直观表示,而不是数据本身。这将导致代码耦合较少,您决定更改UI的影响较小。
答案 1 :(得分:2)
线程无法访问任何表单UI元素,包括读取复选框的任何属性。必须仅从主UI线程调用Control
方法和属性:
使用
InvokeRequired
属性来同步访问 从多个线程控制。对于 有关多线程的更多信息 Windows窗体控件,请参阅How to: Make Thread-Safe Calls to Windows Forms Controls
答案 2 :(得分:2)
答案肯定是肯定的。原因是因为正确访问UI控件状态涉及大量工作。您基本上必须将方法调用封送到UI线程以正确访问控件。该编组操作需要通过包含委托引用的消息泵向UI线程发送消息。 UI线程最终会将其拾取并执行它。由于我从未计算过这个操作,所以我不能确定它有多贵,但我怀疑这是一个非常重要的时间。它必须以这种方式完成,因为UI控件具有线程关联性。这意味着只能在创建它们的线程上访问它们。要编组代理人,请使用Control.Invoke
或Control.BeginInvoke
方法。
public partial class YourForm : Form
{
// Make sure to mark this variable as volatile.
private volatile bool m_Checked;
private void YourForm_Load(object sender, EventArgs e)
{
m_Checked = YourCheckbox.Checked;
var thread = new Thread(
() =>
{
while (true)
{
// This read will come from main memory since the
// variable is marked as volatile.
bool value = m_Checked;
}
});
thread.Start();
}
private void YourCheckbox_CheckedChanged(object sender, EventArgs e)
{
// This write will be committed to main memory since the
// variable is marked as volatile.
m_Checked = YourCheckbox.Checked;
}
}