Microsoft MVP성태의 닷넷 이야기
글쓴 사람
김현준 (munga0828 at naver.com)
홈페이지
첨부 파일
 
안녕하세요?
Datagridview를 통해서 100만개정도의 데이터를 출력시키는 프로그램을 작성하였습니다.
프로그램 사용하는데 있어서 큰 지장은 없지만 약간의 버벅임이 존재하여 확인해본 결과 스크롤시에 GC를 매우 여러번 호출하는 현상을 발견하였습니다.
Virtual Mode를 사용하여 Cellvalueneeded 이벤트를 통해 기존에 존재하는 배열의 인덱스를 참조하여 gridview의 셀에다가 데이터를 넣기만 하는데 GC를 왜이렇게 많이 호출하는지 궁금합니다.
(제 생각에는 매모리 할당 해제가 일어나지 않을것같거든요,.,)

제가 작성한 코드는 아래와 같습니다.
여러번 확인했는데 문제될것은 없어 보이는데.. 혹시 조금 더 효율적인 방법이 있나요?

private void Form1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (e.RowIndex >= ListCF.Count)
            {
                return;
            }

            DataGridView dgv = (DataGridView)sender;

            if (dgv.SelectedCells.Count == 1)
            {
                if (e.RowIndex == dgv.SelectedCells[0].RowIndex && e.ColumnIndex == 0)
                {
                    dgv.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.LightSkyBlue;
                }
                else if (e.ColumnIndex == 0)
                {
                    dgv.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.White;
                }
            }
            else
            {
                dgv.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.White;
            }

            if (dgv.Name == DGV[(int)DGV_DEVICE.CF190].Name)
            {

                switch (e.ColumnIndex)
                {
                    case (int)DGV_HEADER_CF190.NO:
                        e.Value = e.RowIndex + 1;
                        break;
                    case (int)DGV_HEADER_CF190.NAME:
                        if (ListCF[e.RowIndex].rawData_64 == 0xF000000000000000 || ListCF[e.RowIndex].rawData_64 == 0)
                        {
                            e.Value = "-";
                        }
                        else if (DeviceDataInfo[(int)DGV_DEVICE.CF190].ContainsKey(ListCF[e.RowIndex].instructionInt))
                        {
                            e.Value = (DeviceDataInfo[(int)DGV_DEVICE.CF190][ListCF[e.RowIndex].instructionInt].InstName);
                        }
                        else
                        {
                            e.Value = "Instruction ERR";
                        }
                        break;
                    case (int)DGV_HEADER_CF190.INSTRUCTION_s:
                        e.Value = ListCF[e.RowIndex].siSnsrInst65;
                        break;
                    case (int)DGV_HEADER_CF190.BIT13__9:
                        e.Value = ListCF[e.RowIndex].siSnsrBit13__9;
                        break;
                    case (int)DGV_HEADER_CF190.PARITY_s:
                        e.Value = ListCF[e.RowIndex].siSnsrParity;
                        break;
                    case (int)DGV_HEADER_CF190.BIT7__4:
                        e.Value = ListCF[e.RowIndex].siSnsrBit7__4;
                        break;
                    case (int)DGV_HEADER_CF190.DATA_IN_s:
                        e.Value = ListCF[e.RowIndex].siSnsrData;
                        break;
                    case (int)DGV_HEADER_CF190.TFF_s:
                        e.Value = ListCF[e.RowIndex].soSnsrTFF;
                        break;
                    case (int)DGV_HEADER_CF190.TST_s:
                        e.Value = ListCF[e.RowIndex].soSnsrTST;
                        break;
                    case (int)DGV_HEADER_CF190.EOP_s:
                        e.Value = ListCF[e.RowIndex].soSnsrEOP;
                        break;
                    case (int)DGV_HEADER_CF190.SID:
                        e.Value = ListCF[e.RowIndex].soSnsrSID;
                        break;
                    case (int)DGV_HEADER_CF190.DATA_Out_s:
                        e.Value = ListCF[e.RowIndex].soSnsrOutputData;
                        break;
                    case (int)DGV_HEADER_CF190.INSTRUCTION_m:
                        e.Value = ListCF[e.RowIndex].siMdulInstruction;
                        break;
                    case (int)DGV_HEADER_CF190.PARITY_m:
                        e.Value = ListCF[e.RowIndex].siMdulParity;
                        break;
                    case (int)DGV_HEADER_CF190.DATA_IN_m:
                        e.Value = ListCF[e.RowIndex].siMdulInputData;
                        break;
                    case (int)DGV_HEADER_CF190.TFF_m:
                        e.Value = ListCF[e.RowIndex].soMdulTFF;
                        break;
                    case (int)DGV_HEADER_CF190.TST_m:
                        e.Value = ListCF[e.RowIndex].soMdulTST;
                        break;
                    case (int)DGV_HEADER_CF190.EOP_m:
                        e.Value = ListCF[e.RowIndex].soMdulEOP;
                        break;
                    case (int)DGV_HEADER_CF190.BIT12__11:
                        e.Value = ListCF[e.RowIndex].soMdulBit12__11;
                        break;
                    case (int)DGV_HEADER_CF190.WDF:
                        e.Value = ListCF[e.RowIndex].soMdulWDF;
                        break;
                    case (int)DGV_HEADER_CF190.BIT9__8:
                        e.Value = ListCF[e.RowIndex].soMdulBit9__8;
                        break;
                    case (int)DGV_HEADER_CF190.DATA_OUT_m:
                        e.Value = ListCF[e.RowIndex].soMdulData;
                        break;

                }
            }
        }






[최초 등록일: ]
[최종 수정일: 7/3/2017 ]


비밀번호

댓글 쓴 사람
 



2017-07-03 01시37분
위의 코드만 봐서는 구현상 문제는 없어 보이는데요. 스크롤할 때 Form1_CellValueNeeded 코드만 실행되는 것이 맞나요? 아래의 예제 코드로도 100만개 리스트면 재현이 되나요?

How to: Implement Virtual Mode in the Windows Forms DataGridView Control
; https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-implement-virtual-mode-in-the-windows-forms-datagridview-control
정성태
2017-09-16 08시13분
[1] 이벤트 시작 부분의 데이터그리드뷰 생성 부분에 넘어온 구리드 객체를 바로 타입변환을 하지마시고 new 로 생성 후 적용하세요
[손님]

1  2  3  4  5  6  7  8  9  10  11  12  13  [14]  15  ...
NoWriterDateCnt.TitleFile(s)
5008도와주세요7/5/20182197 리스트 아이템의 타입을 추출해서 다시 재활용하고 싶어요.2 [6]파일 다운로드1
5007도와주세요7/4/20182501리스트 아이템의 타입을 추출해서 다시 재활용하고 싶어요. [1]
5006정환나라7/4/20183012소켓 통신과 쓰레드에 관해 질문드립니다 [4]
5005psh7/4/20182198인용에 관련해 문의 드립니다 [1]파일 다운로드2
5004까오리7/4/20181776iis8.0에서 닷넷1.1을 사용하기 위한 질문입니다. [1]
5002멋쟁이7/2/20181749WPFApp에 관한 초보 질문입니다. [1]파일 다운로드1
5001김학완7/1/20182096시작하세요 C# 7.1 프로그래밍 P53쪽 질문입니다. [2]
5000레몬6/26/20182389안녕하세요 성태님 도움으로 C# 네이버 카페 스팸글 작성되면 삭제되는 프로그램을 만들었는데요..여쭤볼게 하나 있습니다. [3]
4999jt6/21/20182260검색어 입력, 엔터 > 페북 로그인창으로 이동합니다. [4]
4998개발희망6/11/20182130C# 형변환 질문있습니다! [1]
4997초보개발자6/5/20187400C++ dll C#에서 사용하는데 보호된 메모리 오류떠요 한번만 도와주세요ㅜ [2]파일 다운로드1
4996swc6/5/20182572현업에서 주로 사용하는 DB업데이트 방법 질문입니다. [1]파일 다운로드1
4993학생6/3/20182129질문 드립니다 [1]
4991최진안5/24/20182162Credential Provider 질문 [2]
4990heygongc5/21/20182122Sybase Adaptive Server Anywhere 6 버전에 대한 질문입니다. [5]
4989강한음5/18/20183030clickonce 배포 후 실행 무응답 [2]
4988C#7.1책구매자5/17/20182171dynamic 키워드를 사용한 객체 핸들링에 대해서 여쭤보려고 합니다. [1]
4987포플러5/14/20182958닥터왓슨 로그 - c0000005 (액세스 위반) 분석 부탁드려도 될까요? [2]
4986익명5/14/20183232비주얼 스튜디오 wpf 프로젝트에서 어떻게 하면 exe파일과 실행에 필요한 파일들을 분리해서 정리해서 디렉토리로 묶을 수 있을까요? [4]
4985대구개발자5/7/20182414새로운 폴더만 "이름 없는 파일" 오류 [1]
4984안중언5/6/20182917교재 143page [1]
4983익명5/4/20186648(wpf) 다른 컴퓨터에서 사용하면 자꾸 ('CefSharp.Core.dll' 또는 여기에 종속되어 있는 파일이나 어셈블리 중 하나를 로드할 수 없습니다)라고 떠요.ㅠㅠ [5]
4982SoulToMind4/27/20182389MFC ActiveX 컨트롤 안에 있는 C# ActiveX 컨트롤 포인터 얻기 [4]
4981대전박4/25/20182235WPF IValueConverter 를 구현해서 StaticResource로 사용할때요 [1]
4980대전박4/23/20182642WPF OS버전 따라 Style 적용이 안되는 프로퍼티가 있을수 있나요? [2]
4979초보개발자4/18/20184475C# 프레임워크 버전이 다른 DLL끼리의 사용 [7]파일 다운로드1
1  2  3  4  5  6  7  8  9  10  11  12  13  [14]  15  ...