How to start a thread to keep GUI refreshed?

前端 未结 4 1044
梦毁少年i
梦毁少年i 2021-02-11 03:04

I have window with button which triggers lengthy processing. I put processing in a separate thread, but -- to my surprise -- it makes GUI frozen anyway. No control is refreshed,

相关标签:
4条回答
  • 2021-02-11 03:53

    I put processing in a separate thread, but -- to my surprise -- it makes GUI frozen anyway.

    I really hate to tell you, but then you did NOT put it into a separate thread. That simlpe.

    There was a poster here that had a similar issue some time ago and through a mistake in his invoking code he basically had all processing before the thread started, with the thread jsut returning the result.

    0 讨论(0)
  • 2021-02-11 03:54

    There are numerous methods to run functions off the UI thread, but the easiest and generally most suitable is to look at the BackgroundWorker component. Many decent tutorials can be found. For example, here.

    0 讨论(0)
  • 2021-02-11 04:04

    I faced the same situation, and solved it by two ways...

    1. Use the thread in other class and invoke it in ur main application by creating Thread, either in its constructor OR in any method.

    2. if u want do the it in same class, then create a Thread that call your function, and that function should invoke the Delegate.

    See the examples:

         public partial class Form1 : Form
        {
            private delegate void TickerDelegate();
            TickerDelegate tickerDelegate1;
    
            public Form1()
            {
                InitializeComponent();
            }
       //first solution
       // This button event call other class having Thread
    
           private void button1_Click(object sender, EventArgs e) 
            {
                f = new FormFileUpdate("Auto File Updater", this);
                f.Visible = true;
                this.Visible = false;         
            }
    
            // Second Solution
            private void BtnWatch_Click(object sender, EventArgs e)
            {
                tickerDelegate1 = new TickerDelegate(SetLeftTicker);
                Thread th = new Thread(new ThreadStart(DigitalTimer));
                th.IsBackground = true;
                th.Start();
             }
    
            private void SetLeftTicker()
            {
                label2.Text=DateTime.Now.ToLongTimeString();
            }
    
    
            public void DigitalTimer()
            {
                while (true)
                {
                    label2.BeginInvoke(tickerDelegate1, new object[] {});
                    Thread.Sleep(1000);
                }
            }
        }
    
    0 讨论(0)
  • 2021-02-11 04:09

    It should be fine as it is. Things which may be freezing your UI:

    • Are you locking within the UI thread, and locking on the same lock in your other thread?
    • Are you calling Join on the thread from your UI thread?
    • Are you doing some other heavy work in the UI thread?

    If you could come up with a short but complete program which shows the problem, I'm sure we could help to fix it... but it certainly should be okay.

    EDIT: Okay, now you've added this:

    The counter of the loop is a property which triggers OnPropertyChanged with each change (classic WPF binding).

    So you're updating the property from the non-UI thread? I would expect that to cause problems, because it will trigger UI changes from the wrong thread.

    I suggest you take an approach such as:

    • Periodically update the counter via Dispatcher.BeginInvoke
    • Have the "UI counter" and the "worker counter" - and copy the value from the "worker counter" to the "UI counter" in the UI thread via a DispatcherTimer, essentially polling it.
    0 讨论(0)
提交回复
热议问题