0

大约一年来,我一直在为制造机器开发 gui(或 HMI)。gui 需要读取访问权限的机器中大约有 5000 个参数。

目前我有一个守护线程从机器收集所有变量作为机器中的几个大数据块并将它们解析出来并将它们放在gui上的列表中。

我在不到 40 毫秒的时间内收集、更新和解析所有内容,这远低于所需的 1 秒的必要更新频率,因此我认为这工作得很好。

那么问题是如何在实际的 gui 中更新控件。因为我只能在创建它的同一线程上更新控件。我目前使用不同的线程循环所有控件,然后使用 BeginInvoke (winform) 或 Dispatcher (wpf) 为用户更新所有内容。这对我来说似乎过于复杂。

有没有人做过类似的事情或者有更优雅的方式来更新 gui?

谢谢!

4

3 回答 3

0

您可以触发执行添加项目、将文本框更新到列表的工作的事件,如下面的使用 ListView 的示例所示。您只需在全局范围内添加变量,以便任何后台工作人员以及 UpdateUiEvent 都可以访问它们。

ListViewItem _listViewItem;

private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
    //your loop to get list view item
    _listViewItem = new ListViewItem(mytext) {tag = mytagobject);
    _listViewItem.SubItems.Add(mysubitemtext);
    Invoke(new EventHandler(UpdateUiEvent), new[] { sender, e });
}

void UpdateUiEvent(object sender, EventArgs e)
{
    listView1.Items.Add(_listViewItem);
}
于 2012-07-12T11:14:10.587 回答
0

尝试使用 BackgroundWorker

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

在 DoWork 事件中收集数据并使用报告进度功能将其分块传递或在结果中一次性传递。它使您无需使用 Invoke。

于 2012-07-12T06:43:37.347 回答
0

还有另一种可选的线程方法,

在构造函数中定义此代码,

     RunAsynchroneWork(new DoWorkEventHandler(RestartOnLoaded), new    RunWorkerCompletedEventHandler(RestartOnLoaded_Completed));

并将以下代码写入相关位置

 //AsynchroneWorker 
    public void RunAsynchroneWork(DoWorkEventHandler workHandler, RunWorkerCompletedEventHandler workCompletedHandler = null)
    {
        BackgroundWorker backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += workHandler;
        if (workCompletedHandler != null) backgroundWorker.RunWorkerCompleted += workCompletedHandler;
        backgroundWorker.RunWorkerAsync();
    }

   public void RestartOnLoaded(object sender, DoWorkEventArgs e)
    {

    //DO SOMETHING HERE   

    }


    public void RestartOnLoaded_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
      //DO SOMETHING HERE ( after completion of RestartOnLoaded ) 
    }
于 2012-07-12T06:48:33.107 回答