必须使用Control.Invoke与在单独线程上创建的控件进行交互

Roy*_*yal 1 .net c# compact-framework

下面是在紧凑框架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();
}
Run Code Online (Sandbox Code Playgroud)

在线程上调用下面的方法

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

错误:

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."}
Run Code Online (Sandbox Code Playgroud)

排队

XMLUtils.CreateAttribute(docEventFile, attributeNode, "value", scanIdValueLabel.Text);
Run Code Online (Sandbox Code Playgroud)

我正在接受Control.Invoke must be used to interact with controls created on a separate thread这条线

XMLUtils.CreateAttribute(docEventFile, attributeNode, "value", scanIdValueLabel.Text);
Run Code Online (Sandbox Code Playgroud)

我用谷歌搜索并尝试了解决方案,但没有为我工作.任何人都可以帮助我这样做.

谢谢

Com*_*ity 9

当你处理Winforms,WPF,Silverlight时,下面的句子非常重要:

UI元素只能由UI线程访问.WinForms,WPF,Silverlight不允许从多个线程访问控件.

但是,有一个解决方案可以在这里找到:

更新:我已经创建了一个示例应用程序来清楚地说明一些事情:

在此输入图像描述

我先创建了一个带有按钮和标签的表单.标签不可见,因为它不包含文本,但它位于按钮下方.

场景1:无线程更新:

private void btnStartThread_Click(object sender, EventArgs e)
{
    lblMessage.Text = "Button has been clicked.";
}
Run Code Online (Sandbox Code Playgroud)

当然这不是问题.这是一些标准代码:

场景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.";
}
Run Code Online (Sandbox Code Playgroud)

这将失败,因为我正在从另一个线程修改我的表单上的控件:

在此输入图像描述

现在,我将修改代码,以便通过标签上的调用通过操作更改标签.

private void ScanEvents()
{
    if (lblMessage.InvokeRequired)
    {
        lblMessage.Invoke((Action)(() => lblMessage.Text = "This text was placed from within a thread."));
    }
}
Run Code Online (Sandbox Code Playgroud)

这将使文本发生变化.

在此输入图像描述

所以,我希望它有所帮助.如果没有,请大喊:-)