C#

BackgroundWorker이벤트에 설정된 처리(DoWork)를 취소하는 방법

지오준 2022. 4. 20.
반응형

BackgroundWorker이벤트에 설정된 처리를 취소하는 방법 입니다.

작업순서는 다음과 같습니다.

 

BackgroundWorker이벤트의 취소처리를 유효화 합니다.

//백그라운드 실행생성
BackgroundWorker worker = new BackgroundWorker();
//백그라운드 취소유효화
worker.WorkerSupportsCancellation = true;

BackgroundWorker이벤트의 실제처리를 Thread로 처리 합니다.

//처리내용을 쓰레드처리
var progressThread = new Thread(() =>
{
    //처리내용추가
    //100초동안 Progress처리(샘플)
    Thread.Sleep(100000);
});
//쓰레드처리실행
progressThread.Start();

//쓰레드실행중일때
while (progressThread.IsAlive)
{
    //백그라운드가 취소된경우
    if (worker.CancellationPending)
    {
        //쓰레드종료
        progressThread.Abort();
        e.Cancel = true;
    }
}

BackgroundWorker이벤트의 취소처리를 추가 합니다.

예를 들어 화면종료시에 BackgroundWorker이벤트를 취소하는 코드를 추가해서 사용할수도 있습니다.

/// <summary>
/// 화면종료직전 이벤트(샘플)
/// </summary>
private void Window_Closing(object sender, CancelEventArgs e)
{
    //다이얼로그화면에서 화면종료 선택시
    if (MessageBox.Show("화면을 닫아도 괜찮겠습니까?", "확인", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
    {
        //백그라운드처리가 실행중인 경우
        if (worker != null && worker.IsBusy)
        {
            //백그라운드처리를 취소
            worker.CancelAsync();
        }
    }
    //화면을 종료안할경우
    else
    {
        e.Cancel = true;
    }
}

샘플코드 및 화면 캡쳐

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ProgressSample
{
    /// <summary>
    /// MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //백그라운드 실행생성
        BackgroundWorker worker = new BackgroundWorker();

        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Progress처리실행버튼 클릭 이벤트 
        /// </summary>
        private void btnProgress_Click(object sender, RoutedEventArgs e)
        {
            //백그라운드 취소유효화
            worker.WorkerSupportsCancellation = true;
            //백그라운드 이벤트설정
            worker.DoWork += ProgressDoWork;
            //백그라운드 완료이벤트설정
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ProgressCompleted);
            //백그라운드 실행
            worker.RunWorkerAsync(100);
            //Progress이미지 표시
            ProgressChange();
        }

        /// <summary>
        /// Progress의 백그라운드상에서의 처리내용
        /// </summary>
        private void ProgressDoWork(object sender, DoWorkEventArgs e)
        {
            //처리내용을 쓰레드처리
            var progressThread = new Thread(() =>
            {
                //처리내용추가
                //100초동안 Progress처리(샘플)
                Thread.Sleep(100000);
            });
            //쓰레드처리실행
            progressThread.Start();
            
            //쓰레드실행중일때
            while (progressThread.IsAlive)
            {
                //백그라운드가 취소된경우
                if (worker.CancellationPending)
                {
                    //쓰레드종료
                    progressThread.Abort();
                    e.Cancel = true;
                }
            }
        }

        /// <summary>
        /// Progress처리완료 이벤트
        /// </summary>
        private void ProgressCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Progress이미지 비표시 처리
            ProgressChange();
        }

        /// <summary>
        /// Progress이미지 표시/비표시 처리
        /// </summary>
        private void ProgressChange()
        {
            // Progress이미지가 표시된 경우
            if (this.loading_image.IsActive)
            {
                // Progress이미지를 비표시
                this.loading_image.IsActive = false;
                this.rec_overlay.Visibility = Visibility.Hidden;
                this.tbl_text.Visibility = Visibility.Hidden;
            }
            // Progress이미지가 비표시된 경우
            else
            {
                // Progress이미지를 표시
                this.loading_image.IsActive = true;
                this.rec_overlay.Visibility = Visibility.Visible;
                this.tbl_text.Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// 화면종료직전 이벤트
        /// </summary>
        private void Window_Closing(object sender, CancelEventArgs e)
        {
            //다이얼로그화면에서 화면종료 선택시
            if (MessageBox.Show("화면을 닫아도 괜찮겠습니까?", "확인", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                //백그라운드처리가 실행중인 경우
                if (worker != null && worker.IsBusy)
                {
                    //백그라운드처리를 취소
                    worker.CancelAsync();
                }
            }
            //화면을 종료안할경우
            else
            {
                e.Cancel = true;
            }
        }
    }
}

ProgressSample.zip
19.27MB

반응형

댓글