C# 在运行时刷新控件

C# 在运行时刷新控件,c#,runtime,refresh,C#,Runtime,Refresh,我正在处理WindowsForm并尝试从文件导入数据,同时我希望在读取新数据后立即将其显示在sreen上 我的基本代码如下所示: public partial class Form1 : Form { public Form1() { InitializeComponent(); Read_in(); } List<Data> _list = new List<Data>(); public vo

我正在处理WindowsForm并尝试从文件导入数据,同时我希望在读取新数据后立即将其显示在sreen上

我的基本代码如下所示:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Read_in();
    }

    List<Data> _list = new List<Data>();

    public void Read_in()
    {
        using (StreamReader sr = new StreamReader("in.txt"))
        {
            while (!sr.EndOfStream)
            {
                Data d = new Data
                {
                    a = sr.ReadLine()
                };
                _list.Add(d);
                Controls.Add(d.pb);
            }
        }
    }
}

class Data
{
    public string a;
    public PictureBox pb = new PictureBox()
    {
        BackColor = Color.Red
    };
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
读入;
}
列表_List=新列表();
公共无效读入()
{
使用(StreamReader sr=newstreamreader(“in.txt”))
{
而(!sr.EndOfStream)
{
数据d=新数据
{
a=高级读线()
};
_列表.添加(d);
添加(d.pb);
}
}
}
}
类数据
{
公共字符串a;
公共PictureBox pb=新PictureBox()
{
背景色=颜色。红色
};
}
问题是我的数据仅在Read_in()完成时显示。我能帮上什么忙

这里有一篇类似于此的帖子,但我无法理解:
这是因为数据是在UI线程中读取的。您必须生成一个新线程并加载其中的数据,从而释放UI线程进行更新

正如阿列克谢所说,这里有一点解释:

请注意,只要在通常的进程中执行UI更新,UI线程就会被阻塞,而在多线程进程中,后台工作程序会执行所有更新,您需要注意的只是同步

请按以下方式修改代码并让我知道:

public void Read_in()
{
    BackgroundWorker backgroundWorker1 = new BackgroundWorker();
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerAsync();

}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    using (StreamReader sr = new StreamReader("in.txt"))
    {
        while (!sr.EndOfStream)
        {
            Data d = new Data
            {
                a = sr.ReadLine()
            };
            if(this.InvokeRequired)
            {
                 this.Invoke((MethodInvoker)delegate
                 {
                     _list.Add(d);
                     Controls.Add(d.pb);
                 });

            }
            else
            {
                 _list.Add(d);
                 Controls.Add(d.pb);

            }
        }
    }
}

一根线就像超市里的一条线。现在想想你只有一次结账。拿着你文件的人在结账。那个画控件的家伙在队伍的后面。画画的人不能在结账时付款,所以他不能画控件。所以他因为收银台上的档案员被封锁了

您的gui线程是通向签出的线路。一种方式,绘画的家伙可以通过结帐是打开另一个结帐。这样他就可以付款并结账了。之后,他就可以画控件了。因此,打开另一个现金就是打开一个新的线程。在新线程上,您可以读取文件。有了这个,画画的家伙就不会通过文件的家伙被阻止结账了

或者您在收银台上设置了两名女士:
这样签出就不会被文件管理员阻止。

+0:注意,你的帖子正是OP评论的“我不明白”。。。我不确定你的这句话如何比链接文章更好地解释冻结用户界面的概念。谢谢你,它很有效。你帮助我了解了一个新事物!:)@有必要写一份清单,加上(d);在if(this.invokeRequired)语句中?一点也不,但您可能希望使用某种同步,以确保BackgroundWorker执行操作时,没有其他线程触及
\u list
。对于当前示例,您可以将
\u列表
调用所需的
块中取出。