Refreshing Controls in runtime

耗尽温柔 提交于 2019-12-13 06:04:59

问题


I'm working on a WindowsForm and trying to import data from a file, meanwhile I'd like to display the new data on sreen as soon as I read it in.

My basic code looks like this:

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
    };
}

The problem is that my data is only displayed when Read_in() is finished. How can I help this?

Here's a post similar to this one, but I couldn't understand it: Why won't control update/refresh mid-process


回答1:


Thats because the data is being read in the UI thread. You will have to spawn a new thread and load data in that, thus freeing the UI thread for updates.

As Alexei suggested here is the bit of explanation:

Note that the UI thread is blocked as long as UI update is being performed in usual process, whereas in multithreaded process, background worker does all the updation all you need to take care of is the Syncing.

Please modify the code as follows and let me know:

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);

            }
        }
    }
}



回答2:


A thread is like a line in the supermarket. Now think that you have only one checkout. The guy with your files is on the checkout. And the guy with the painting for the controls is in the back of the line. The painting guy cant pay on the checkout, so he can't paint the controls. So he is blocked because of the file guy on the checkout.

Your gui thread is the line to the checkout. A way that the painting guy can go through the checkout is to open another checkout. So he can pay and go through the checkout. After that he can paint the controls. So to open another cash is to open a new thread. On the new thread you can do the file reading. With that the painting guy is not blocked on the checkout through the file guy.

Or you set two woman on the checkout with: http://msdn.microsoft.com/de-de/library/system.io.streamreader.readlineasync(v=vs.110).aspx so that the checkout is not block trough the file guy.



来源:https://stackoverflow.com/questions/20688838/refreshing-controls-in-runtime

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!