퇴근5분전

 

 프로그램을 만들때 비동기로 처리하고 싶다거나

 프로그래스 바로 진행율같은걸 표시하고 싶을때나...

 

사용하면 엄청 편하게 사용이 가능하다.

 

task나 await 같은 비동기... 처리도 있지만... ( 머리가 나쁘니 이해하는데 오래 걸리긴 한데... )

 

## 소스 사용예제

                       // todo : Excel Export
                        AsyncManagerClass async = new AsyncManagerClass();
                        async.BeforeAsyncCall = () => {
                            button1.DoInvoke(b => b.Enabled = false);  <-- 크로스 쓰레드를 회피! 하는 Invoke!
                            progressBar1.DoInvoke(p =>
                            {
                                p.Minimum = 0;
                                p.Maximum = src.Rows.Count -1;
                            });
                        };
                        async.AfterAsyncCall = () => {
                            button1.DoInvoke(b => b.Enabled = true);
                        };
                        async.Async(() => {
                            ExportToExcel(src);   <--- 비동기로 뭔가 열심히 처리 할수 있는 Method!
                        });

 

 

async.Async 내에서 호출되는 컨트롤들은 모두

             .DoInvoke( c => ... );  로 묶어서 처리 해주면 된다.

 

private void ExportToExcel(DataTable src)
{

    ... 생략 ...
    try
    {

        for (int row = 0; row < src.Rows.Count; row++)
        {
            progressBar1.DoInvoke( p => p.Value = row );

            ... 생략 ...   

        }
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

}

 

 

 #region 비동기 처리
    public class AsyncManagerClass
    {
        public Action BeforeAsyncCall = null;

        public Action AfterAsyncCall = null;

        public void Async(Action doActionMethod)
        {
            if (BeforeAsyncCall != null)
                BeforeAsyncCall();

            IsRun = true;
            if (doActionMethod != null)
            {
                doActionMethod.BeginInvoke(ir =>
                {
                    try
                    {
                        doActionMethod.EndInvoke(ir);

                        if (AfterAsyncCall != null)
                        {
                            AfterAsyncCall();
                        }
                    }
                    catch
                    {
                        // 작업 중!! 예외
                    }
                    IsRun = false;
                }, null);
            }

        }

        public void Stop()
        {
            IsRun = false;
        }

        public bool IsRun { get; set; }
    }

    public static class Ex
    {
        public static void DoInvoke<T>(this T ctrl, Action<T> callMethod) where T : Control
        {
            if (ctrl.InvokeRequired)
            {
                ctrl.Invoke(new Action<T, Action<T>>(DoInvoke), ctrl, callMethod);
            }
            else
            {
                callMethod(ctrl);
            }
        }
    }
    #endregion