下面是在紧凑框架3.5中启动线程的方法
public ScanEntry(string scanId)
{
InitializeComponent();
_scanId = scanId;
//reader = deviceFactory.Create();
//reader.YMEvent += new ScanEventHandler(reader_Reading);
//reader.Enable();
}
private void CasesEntry_Load(object sender, EventArgs e)
{
caseCounterLabel.Text = cases.Count.ToString();
scanIdValueLabel.Text = _scanId;
}
internal void menuItemNewScan_Click(object sender, EventArgs e)
{
System.Threading.ThreadStart threadDelegate = new System.Threading.ThreadStart(ScanEvents);
System.Threading.Thread newThread = new System.Threading.Thread(threadDelegate);
newThread.Start();
}
在线程上调用以下方法
private void ScanEvents()
{
try
{
//some other codes
if (scanIdValueLabel.InvokeRequired)
{
scanIdValueLabel.Invoke((Action)(() => scanIdValueLabel.Text = "value"));
}
attributeNode = docEventFile.CreateNode(XmlNodeType.Element, "Attribute", string.Empty);
XMLUtils.CreateAttribute(docEventFile, attributeNode, "name", "SCANID");
XMLUtils.CreateAttribute(docEventFile, attributeNode, "value", scanIdValueLabel.Text);
attributeSetNode.AppendChild(attributeNode);
//some other codes
}
catch(Execption e)
{
Message.Show(e.Message);
}
}
错误:
TextAlign = 'scanIdValueLabel.TextAlign' threw an exception of type 'System.NotSupportedException'
base {System.SystemException} = {"Control.Invoke must be used to interact with controls created on a separate thread."}
在线
XMLUtils.CreateAttribute(docEventFile, attributeNode, "value", scanIdValueLabel.Text);
我在这一行得到Control.Invoke must be used to interact with controls created on a separate thread
XMLUtils.CreateAttribute(docEventFile, attributeNode, "value", scanIdValueLabel.Text);
我用谷歌搜索并尝试了解决方案,但没有为我工作。任何人都可以帮助我这样做。
由于
答案 0 :(得分:8)
当您与Winforms,WPF,Silverlight打交道时,下面的句子非常重要:
UI元素只能由UI线程访问。 WinForms,WPF,Silverlight不允许从多个线程访问控件。
但是,有一个解决方案可以找到here:
更新:我已经创建了一个示例应用程序,以便明确一些事项:
我先创建了一个带有按钮和标签的表单。标签不可见,因为它不包含文字,但它位于按钮下方。
场景1:无线程更新:
private void btnStartThread_Click(object sender, EventArgs e)
{
lblMessage.Text = "Button has been clicked.";
}
当然这不是问题。这是一些标准代码:
场景2:使用线程进行更新:
private void btnStartThread_Click(object sender, EventArgs e)
{
System.Threading.ThreadStart threadDelegate = new System.Threading.ThreadStart(ScanEvents);
System.Threading.Thread newThread = new System.Threading.Thread(threadDelegate);
newThread.Start();
}
private void ScanEvents()
{
lblMessage.Text = "Exected in another thread.";
}
这会失败,因为我修改了另一个帖子中表单上的控件:
现在,我将修改代码,以便通过标签上的调用通过操作更改标签。
private void ScanEvents()
{
if (lblMessage.InvokeRequired)
{
lblMessage.Invoke((Action)(() => lblMessage.Text = "This text was placed from within a thread."));
}
}
这将使文本发生变化。
所以,我希望它有所帮助。如果没有,请大喊: - )