윈폼 컨트롤 사용시 타 쓰레드에서 컨트롤 변경호출시 컨트롤의 InvokeRequired 확인하고 처리하는 코드가 너저분해지기 마련입니다.

이런 류 코드는 많이 쓰일 것 같은데... 



간단히 이렇게도 가능하지만, 

   textBox1.Invoke( new Action (() => { textBox1.Text = count.ToString(); } ));



좀 더 효율적으로 동작하기 위한 방법들을 찾아보았습니다.
아래 링크에 좋은 의견들이 많았습니다.
그 중 깔끔하게 사용하는 방법을 옮겨 포스팅합니다.




WinForm.cs (아래처럼 활용하시면 됩니다.)
-----------------------------------------------------------
//메인쓰레드가 아닌 다른 쓰레드에서 UI 변경 호출시
label1.RunOnUIThread(control =>
{

     control.Text = $"{progressCount}/{totalCount}";;

});





다음 확장메소드를 선언합니다.


ControlExtension.cs

----------------------------------------------------------------------------


using System.ComponentModel;

namespace RxTestWinForm
{
    public static class ControlExtension
    {
        /// <summary>
        /// T Type의 Delegate  선언
        /// </summary>
        /// <typeparam name="T">T타입</typeparam>
        /// <param name="obj">Invoke 할 컨트롤 </param>
	public delegate void RunOnUIThreadDelegate<T>(T obj) where T : ISynchronizeInvoke;
        /// <summary>
        /// ISynchoronizeInvoke 인터페이스 구현체 대한 RunOnUIThread확장 메소드
        /// </summary>
        /// <typeparam name="T">T타입, 캐스팅을 피하기 위해 사용</typeparam>
        /// <param name="obj">메소드 확장할 컨트롤</param>
        /// <param name="action">수행할 Action</param>
        public static void RunOnUIThread<T>(this T obj, RunOnUIThreadDelegate<T> action)
            where T : ISynchronizeInvoke
        {
            if (obj.InvokeRequired)
            {
                obj.Invoke(action, new object[] { obj });
            }
            else
            {
                action(obj);
            }
        }
    }
}








+ Recent posts