iT邦幫忙

0

[C#] Listbox 與 List更新,畫面會卡住

edl 2022-01-08 14:39:032618 瀏覽
  • 分享至 

  • xImage

我用Listbox顯示List的內容

BindingSource bs = new BindingSource();
bs.DataSource = tempList;   //tempList是其他地方會塞資料進去的         
listMessage.DataSource = bs;


bs.ResetBindings(false);//這會定期呼叫

我遇到的問題是
當tempList Add太快的時候,Listbox畫面就會卡住
大概是少於10ms塞一次就會卡住
只能重開畫面才會正常顯示
但我去點選他select index是會變更的,只是畫面都不會動

測試過幾個可能
短時間塞100個或塞5個資料
重新設定DataSource
都沒用
請問有人遇過這問題嗎

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
Samuel
iT邦好手 1 級 ‧ 2022-01-10 14:07:55
最佳解答

要不要嘗試改多執行緒程式撰寫
winform預設不允許跨thread存取控制項預設要取消這個機制

可以參考看看

winform預設單thread (UI thread)執行會有介面卡頓卡死等待的問題
會卡的寫法

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

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

        private void button1_Click(object sender, EventArgs e)
        {
            BindingSource bindingSource = new BindingSource();
            bindingSource.DataSource = GetData();
            listBox1.DataSource = bindingSource;
        }


        private List<string> GetData()
        {
            List<string> lsData = new List<string>();
            for(int i = 0; i < 500000; i++)
            {
                lsData.Add(string.Format("data{0}", i));
            }
            return lsData;
        }
    }
}

調整過後不會卡的寫法(可以放一個label在上面觀察更新)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ListBoxPerformanceTuning
{
    public partial class Form1 : Form
    {
        Thread thDataRetrieve = null;
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            BindingSource bindingSource = new BindingSource();
            List<string> lsData = new List<string>();
            Task.Factory.StartNew(() =>
            {                
                for (int i = 0; i < 10000; i++)
                {
                    string msg = string.Format("data{0}", i);
                    label1.Text = msg;
                    lsData.Add(msg);
                }
            }).ContinueWith(t =>
            {
                bindingSource.DataSource = lsData;
                listBox1.DataSource = bindingSource;
            });
        }
    }
}

0
Gary
iT邦好手 1 級 ‧ 2022-01-09 10:15:52

初步看歸納成效能問題,以下參考看看!

VirtualizingPanel.VirtualizationMode="Recycling"

https://stackoverflow.com/questions/25530354/improve-performance-for-huge-listbox-in-stackpanel

我要發表回答

立即登入回答