! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

C# .NET에서 데이터를 로드하는 동안 진행률을 나타내는 진행 표시줄 표시하는 방법 > 블로그 & Tips

본문 바로가기

ComponentOne

블로그 & Tips

C# .NET에서 데이터를 로드하는 동안 진행률을 나타내는 진행 표시줄 표시하는 방법

페이지 정보

작성자 MESCIUS 작성일 2023-11-23 10:43 조회 191회 댓글 0건

본문

응용 프로그램을 설계할 때는 응용 프로그램이 항상 사용자에게 응답할 수 있도록 데이터 로딩을 처리하는 방법에 대해 고려해야 합니다.


이는 일반적으로 사용자가 응용 프로그램과 상호 작용하는 동안 백그라운드 스레드에서 비동기적으로 데이터를 로드하여 수행됩니다. 


문제는 적절한 시각화가 없을 시 사용자가 무슨 일이 일어나고 있는지 알 수 없어 궁금할 수 있다는 것입니다.

따라서 일부 활동이 백그라운드에서 실행되고 있음을 나타내는 진행 표시줄을 사용하게 됩니다. 


데이터가 로드되면 진행 표시줄이 숨겨지고 데이터를 표시하는 관련 컨트롤이 나타납니다.

데이터를 로드하는 동안 진행률 대화 상자 표시


이번 블로그에서는 비동기 데이터 로딩을 통해 WinForms 및 WPF의 진행 표시줄을 사용하는 몇 가지 예를 제시합니다.


또한 비동기식 프로세스를 사용하여 이를 수행하는 방법을 보여 줄 것입니다.



비동기(Asynchronous) 작업에 대한 불확정적(Indeterminate) 진행 표시줄 


첫 단계는 평소보다 로드 시간이 길어지더라도 응용 프로그램 UI가 계속 응답할 수 있도록 데이터를 비동기적으로 로드하는 것입니다.


이는 대기 중인 메서드 호출을 사용하여 .NET에서 쉽게 처리됩니다.


다시 말하면, 대기 이후 발생하는 코드는 작업이 완료되기 전까지는 실행되지 않음을 의미합니다.


아래에서 보시는 것과 같이 가장 쉬운 솔루션입니다.

private async Task LoadData()
{
        // show progress bar
        progressBar1.Visible = true;
        await LoadDataAsync();
        // hide progress bar
        progressBar1.Visible = false;
}


우리가 해야 하는 일은 데이터 로드를 기다리기 전에 진행 표시줄 표시 여부를 설정한 다음, 작업이 완료되면 보이지 않도록 지정하는 것 뿐입니다. 


이것은 진행 표시줄이 "불확정적(Indeterminate)" 상태인 경우에 잘 작동합니다.


즉, 사용자가 중지할 때까지 무한대로 로딩 애니메이션을 반복한다는 뜻입니다.


오늘날 데이터가 로딩될 때 불확정적 진행 표시줄 또는 링을 표시하는 것이 일반적인 디자인 패러다임입니다.


이는 예측할 수 없는 네트워크로 인해 시간이 얼마나 걸릴지 정확히 알 수 없는 상황에 많이 사용됩니다.


호출하는 서버 실행 시간이 얼마나 걸릴지 알려줄 수 없거나 알려주지 않으려 할 수도 있습니다.


WinForms에서 불확정적 진행 표시줄을 만들려면 Style 속성을 Marquee로 설정합니다.


WPF에서는 IsIndeterminate 속성을 True로 설정합니다.



연속적인 진행 표시줄 


불확정적 진행 표시줄의 단점은 시간이 얼마나 남아 있는지 사용자가 알지 못한다는 것입니다.


대안은 데이터가 로드될 때 진행 표시줄에 진행 상태를 보고하는 것입니다.


해당 접근 방식은 사용자가 진행 상황(그리고 때로는 시간이 얼마나 남았는지)을 정확하게 알 수 있어 소프트웨어 설치 시 많이 사용됩니다.


데이터 솔루션에 따라 데이터 로드 중에 사용할 수도 있습니다.

데이터를 로드하는 동안 진행률 대화 상자 표시


진행 표시줄 업데이트를 완벽히 제어할 수 있도록 코드 대기가 아닌 백그라운드 워커를 사용하는 코드 예제를 살펴보겠습니다.

BackgroundWorker worker = new BackgroundWorker();

public App()
{
    InitializeComponent();

    // set background worker
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.WorkerReportsProgress = true;

}


백그라운드 워커를 설정하려면 ProgressChanged, RunWorkerCompleted 및 DoWork 이벤트를 수신해야 합니다.


각각의 경우 수행할 작업은 다음과 같습니다.

  • DoWork: 응용 프로그램의 실제 작업(예: 데이터 로드)을 수행하고, 가능한 경우 ReportProgress 메서드를 사용하여 진행 표시줄에 진행을 보고합니다. 그러면 ProgressChanged 이벤트가 트리거됩니다. 데이터를 로드하는 경우 청크로 로드하면서 중간에 진행을 보고합니다.

  • ProgressChanged: 진행 표시줄의 실제 값을 업데이트합니다. 이 이벤트는 매개 변수를 허용하므로 워크로드에 따라 가변적인 양을 전달할 수 있습니다.

  • RunWorkerCompleted: 진행 표시줄 숨기기 또는 사용자에게 메시지 표시 등 진행을 완료합니다.


이 전체 프로세스를 시작하려면 RunWorkerAsync 메서드를 호출하기만 하면 됩니다.

// run background worker
worker.RunWorkerAsync();  


전체 예제를 보려면 WinForms Control Explorer에서 "Performance" FlexGrid 데모를 확인해 보세요!



모든 것을 비동기화하는 방법 


위 예제는 데이터가 이미 비동기적으로 로드되고 있는 경우에 원활하게 작동합니다.


데이터를 비동기적으로 또는 백그라운드 스레드에서 로드하는 것은 사용자에게 진행률을 표시하기 위한 핵심입니다.


그러나 위의 비동기 메서드를 통해 모든 것이 지원되는 것은 아닙니다.

특히 UI 컨트롤의 업데이트는 UI 스레드에서 이루어지기 때문에 지원되지 않습니다.


다음은 비동기가 아닌 코드를 비동기 코드로 만드는 방법을 보여주는 두 가지 예입니다.


첫 번째 예시에서는 IAsyncAction 인터페이스를 이용합니다.


그러면 반환 객체 없이 일부 코드를 수행할 수 있습니다.


Dispatcher를 사용해 다른 스레드에서 UI 컨트롤에 액세스합니다.

public IAsyncAction LoadSomethingAsync()  
{  
    return Task.Run(() =>  
    {  
        Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>  
            {  
                // do stuff to your UI  
            });  
    }).AsAsyncAction();  
}  


위 코드는 그다지 예쁘지는 않습니다. 하지만 메서드 호출을 명쾌하고 단순하게 만듭니다.


호출하기 전에 await 키워드를 사용하면 비동기식으로 실행됩니다.


사전에 progressRing을 활성화하여 테스트할 수 있으며, 긴 작업이 계속되는 동안 지속적으로 회전합니다.

progressRing.IsActive = true;  
await LoadSomethingAsync();  
progressRing.IsActive = false;  


두 번째 접근 방식은 ThreadPool 클래스를 활용하는 것입니다. 

실행 중에 UI 스레드를 차단하지 않으면서 컴퓨팅 중심의 작업을 대기열에 추가합니다.


이번에는 Dispatcher 호출을 기다릴 수 있도록 메서드에 async 키워드를 사용합니다.

public async void LoadSomething()  
{  
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>  
            {  
                // do stuff to your UI  
            });  
}  


이 메서드는 첫 번째 예시보다 조금 더 깔끔하지만 호출하기 위한 코드는 조금 더 깁니다.

progressRing.IsActive = true;  
await ThreadPool.RunAsync(delegate { LoadSomething(); });  
progressRing.IsActive = false;  



WPF에 대한 사용자 정의 진행 표시줄 


ComponentOne은 WPF에 대한 사용자 정의 진행 표시줄 컨트롤을 제공합니다.


C1ProgressBar 컨트롤은 최신 사용자 환경을 제공하기 위해 Windows 8-10에 사용된 기본 진행 표시기를 모델로 합니다.


불확정적 작업이 진행 중임을 나타내기 위해 애니메이션 반복 패턴으로 이를 표시할 수 있습니다.


또한 C1ProgressIndicator 컨트롤은 로딩 링을 표시합니다.

데이터를 로드하는 동안 진행률 대화 상자 표시

C1.WPF 핵심 라이브러리의 일부로 C1ProgressBar 및 C1ProgressIndicator 컨트롤을 다운로드할 수 있습니다!


 




지금 바로 ComponentOne을 다운로드하여 직접 테스트해 보세요!

c1.png

  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.