ListBox in Break Mode

MiPakTeh 1,476 Reputation points
2021-02-27T06:44:44.997+00:00

Hi All,

The future I want use ListBox. Then Fill the ListBox with a lot of Items.We find the error as bellow;

Managed Debugging Assistant 'ContextSwitchDeadlock'
Message=Managed Debugging Assistant 'ContextSwitchDeadlock' : 'The CLR has been unable to transition from COM context 0xed8788 to COM context 0xed86d0 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.'

This is code;
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 Learning_10
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 5000000; i++)
            {
                listBox1.Items.Add(i);
            }

            vScrollBar1.Maximum = listBox1.Items.Count;

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            vScrollBar1.Height = listBox1.Height;
            vScrollBar1.Left = listBox1.Left + listBox1.Width;
            vScrollBar1.Top = listBox1.Top;
        }

        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            listBox1.TopIndex = e.NewValue;
        }

    }
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,484 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 82,326 Reputation points
    2021-02-27T07:31:58.773+00:00

    You can use a thread to avoid blocking the UI
    But a Listbox is limited
    For a large amount of items, you must use Virtual ListViews or DGV

    A test with 50000 items and a thread to replace your loop in button1_Click :

            System.Threading.Thread bkgrndThread = new System.Threading.Thread(this.BackgroundThread);
            bkgrndThread.IsBackground = true;
            bkgrndThread.Name = "Background Thread";
            bkgrndThread.Start();
    

    the thread :

        public void BackgroundThread()
        {
            for (int i = 0; i < 50000; i++)
            {
                listBox1.Invoke((Action)(() => listBox1.Items.Add(i)));
            }
            vScrollBar1.Invoke((Action)(() => vScrollBar1.Maximum = listBox1.Items.Count)); 
        }
    
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Viorel 113.8K Reputation points
    2021-02-27T09:21:22.977+00:00

    In case of very large number of items, it is problematic or impossible to populate and manage the control. For such case, consider a ListView, which is put into virtual mode. (ListView can be used like a better ListBox with multiple columns, icons, header).

    Instead of adding all of the items, you will set VirtualListSize to the number of items, and will handle the RetrieveVirtualItem event to supply the required (visible) items. There are some other events that can be handled.

    To activate virtual mode, set VirtualMode to true.

    See a sample: https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.listview.virtualmode.

    0 comments No comments