본문 바로가기
C#/책 예제

C# Task 비동기 API WInform 예제

by HyunS_ 2019. 6. 8.
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileCopy
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {
        // Constructor (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 이벤트를 설정합니다.

            this.sourceButton.Click += sourceButton_Click;
            this.targetButton.Click += targetButton_Click;
            this.asyncButton.Click  += asyncButton_Click;
            this.syncButton.Click   += syncButton_Click;
            this.cancelButton.Click += cancelButton_Click;

            #endregion
        }

        #endregion

        // Event Method (Private)

        #region sourceButton_Click(sender, e) - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void sourceButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            if(openFileDialog.ShowDialog() == DialogResult.OK)
            { 
                this.sourceTextBox.Text = openFileDialog.FileName;
            }
        }

        #endregion
        #region targetButton_Click(sender, e) - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void targetButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.targetTextBox.Text = saveFileDialog.FileName;
            }
        }

        #endregion
        #region asyncButton_Click(sender, e) - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private async void asyncButton_Click(object sender, EventArgs e)
        {
            long totalCopied = await CopyAsync(this.sourceTextBox.Text, this.targetTextBox.Text);
        }

        #endregion
        #region syncButton_Click(sender, e) - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void syncButton_Click(object sender, EventArgs e)
        {
            long totalCopied = CopySync(this.sourceTextBox.Text, this.targetTextBox.Text);
        }

        #endregion
        #region cancelButton_Click(sender, e) - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void cancelButton_Click(object sender, EventArgs e)
        {
            MessageBox.Show("UI 반응 테스트 성공");
        }

        #endregion

        // Method (Private)

        #region CopyAsync(fromPath, toPath) - 비동기 방식으로 파일을 복사합니다.

        /// <summary>
        /// 비동기 방식으로 파일을 복사합니다.
        /// </summary>
        /// <param name="fromPath">선택 파일 경로 입니다.</param>
        /// <param name="toPath">복사할 파일 경로 입니다.</param>
        /// <returns></returns>
        private async Task<long> CopyAsync(string fromPath, string toPath)
        { 
            this.syncButton.Enabled = false;
            long totalCopied = 0;

            using(FileStream fromStream = new FileStream(fromPath, FileMode.Open))
            {
                using(FileStream toStream = new FileStream(toPath, FileMode.Create))
                {
                    byte[] buffer = new byte[1024 * 1024];
                    int nRead = 0;

                    while((nRead = await fromStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                    { 
                        await toStream.WriteAsync(buffer, 0, nRead);
                        totalCopied += nRead;

                        this.copyProgressBar.Value = (int)(((double)totalCopied / (double)fromStream.Length) * this.copyProgressBar.Maximum);
                    }
                }
            }

            this.syncButton.Enabled = true;

            return totalCopied;
        }

        #endregion

        #region CopySync(fromPath, toPath) - 동기 방식으로 파일을 복사합니다.

        /// <summary>
        /// 동기 방식으로 파일을 복사합니다.
        /// </summary>
        /// <param name="fromPath">선택 파일 경로 입니다.</param>
        /// <param name="toPath">복사할 파일 경로 입니다.</param>
        /// <returns></returns>
        private long CopySync(string fromPath, string toPath)
        { 
            this.asyncButton.Enabled = false;
            long totalCopied = 0;

            using (FileStream fromStream = new FileStream(fromPath, FileMode.Open))
            {
                using (FileStream toStream = new FileStream(toPath, FileMode.Create))
                {
                    byte[] buffer = new byte[1024 * 1024];
                    int nRead = 0;

                    while ((nRead = fromStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        toStream.Write(buffer, 0, nRead);
                        totalCopied += nRead;

                        this.copyProgressBar.Value = (int)(((double)totalCopied / (double)fromStream.Length) * this.copyProgressBar.Maximum);
                    }
                }
            }

            this.asyncButton.Enabled = true;

            return totalCopied;
        }

        #endregion
    }
}

 

728x90

댓글