Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 11개 있습니다.)
.NET Framework: 612. UWP(유니버설 윈도우 플랫폼) 앱에서 콜백 함수 내에서의 UI 요소 접근 방법
; https://www.sysnet.pe.kr/2/0/11071

.NET Framework: 680. C# - 작업자(Worker) 스레드와 UI 스레드
; https://www.sysnet.pe.kr/2/0/11287

.NET Framework: 777. UI 요소의 접근은 반드시 그 UI를 만든 스레드에서!
; https://www.sysnet.pe.kr/2/0/11561

.NET Framework: 805. 두 개의 윈도우를 각각 실행하는 방법(Windows Forms, WPF)
; https://www.sysnet.pe.kr/2/0/11802

.NET Framework: 886. C# - Console 응용 프로그램에서 UI 스레드 구현 방법
; https://www.sysnet.pe.kr/2/0/12139

.NET Framework: 911. Console/Service Application을 위한 SynchronizationContext - AsyncContext
; https://www.sysnet.pe.kr/2/0/12231

.NET Framework: 1022. UI 요소의 접근은 반드시 그 UI를 만든 스레드에서! - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/12537

.NET Framework: 2076. C# - SynchronizationContext 기본 사용법
; https://www.sysnet.pe.kr/2/0/13190

.NET Framework: 2077. C# - 직접 만들어 보는 SynchronizationContext
; https://www.sysnet.pe.kr/2/0/13191

닷넷: 2278. WPF - 스레드에 종속되는 DependencyObject
; https://www.sysnet.pe.kr/2/0/13682

닷넷: 2298. C# - Console 프로젝트에서의 await 대상으로 Main 스레드 활용하는 방법
; https://www.sysnet.pe.kr/2/0/13743




Console/Service Application을 위한 SynchronizationContext - AsyncContext

일반적으로 WPF/WinForm 프로그램을 하면서 SynchronizationContext를 접하게 되는데요, 사실 마이크로소프트가 제공해주는 기본 클래스에 불과하고 WPF는 DispatcherSynchronizationContext로, WinForm은 WindowsFormsSynchronizationContext로 하위 클래스를 정의하는 방식입니다.

즉, Console 응용 프로그램이나 NT Service 프로그램을 위해서 정의할 수 있지만 일단은 마이크로소프트에서 그런 환경을 위한 SynchronizationContext는 만들지 않았을 뿐입니다. 그렇다면 당연히, 만들면 됩니다. ^^ 그리고 실제로 그걸 다음의 라이브러리에서 제공하고 있습니다.

StephenCleary / AsyncEx
; https://github.com/StephenCleary/AsyncEx

Install-Package Nito.AsyncEx -Version 5.0.0

위의 라이브러리에서 SynchronizationContext를 구현한 타입은 AsyncContext인데,

AsyncContext
; https://github.com/StephenCleary/AsyncEx/wiki/AsyncContext

링크에서 설명한 바와 같이 AsyncContext.Run을 통해 실행한 이후부터는,

class Program
{
  static async Task<int> AsyncMain()
  {
    // ... 이 내부에서 SynchronizationContext가 제공됨
  }

  static int Main(string[] args)
  {
    return AsyncContext.Run(AsyncMain);
  }
}

SynchronizationContext가 해당 스레드 문맥에 제공되므로 Post/Send 메서드로 SynchronizationContext의 기능을 수행할 수 있습니다.




그런데, 사실 Console 응용 프로그램 등에서 저걸 써야 할 상황이 얼마나 있을까? 하는 의문이 듭니다. 만약 써야 한다면, 아마도 멋들어진 CUI를 구현해 그것을 UI로 두고 동기화를 지키는 용도로 쓰면 될 테지만... 글쎄요, 분명 활용도가 많지 않아 보입니다. (마이크로소프트가 만들어 두지 않은 이유일 것입니다.)

그래도 저 같은 사람한테는 편한 용도가 하나 있긴 합니다. 가령, 다음과 같은 글을 쓰면서,

WebClient 타입의 ...Async 메서드 호출은 왜 await + 동기 호출 시 hang 현상이 발생할까요?
; https://www.sysnet.pe.kr/2/0/11419

재현 코드를 만들기 위해 프로젝트 유형을 Windows Forms로 했는데, 이제는 그냥 AsyncEx를 참조해 콘솔 응용 프로그램으로도 간단한 재현 프로그램을 만들 수 있게 되었습니다. ^^ 실제로 다음의 코드는 "WebClient 타입의 ...Async 메서드 호출은 왜 await + 동기 호출 시 hang 현상이 발생할까요?" 글에 실은 예제와 정확히 동일한 hang 현상을 겪습니다.

using Nito.AsyncEx;
using System;
using System.Net;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    // Install-Package Nito.AsyncEx -Version 5.0.0
    class Program
    {
        static void Main(string[] args)
        {
            AsyncContext.Run(AsyncMain);
        }

        static async Task<int> AsyncMain()
        {
            Uri uri = new Uri("https://www.naver.com");

            Task<string> textTask = GetHtmlTextAsync(uri);

            string result = textTask.Result; // hang 현상 발생함.
            return 0;
        }

        public static async Task<string> GetHtmlTextAsync(Uri uri)
        {
            var client = new WebClient();
            {
                string result = await client.DownloadStringTaskAsync(uri).ConfigureAwait(false);
                return result;
            }
        }
    }
}

뭐... 딱 그 정도... 활용 사례입니다. ^^;




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 9/26/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 136  137  138  139  140  [141]  142  143  144  145  146  147  148  149  150  ...
NoWriterDateCnt.TitleFile(s)
1563정성태1/3/201429595오류 유형: 201. ASP.NET 웹 사이트를 IIS 7 이상의 환경에서 호스팅할 때 500 오류 발생
1562정성태1/2/201434265.NET Framework: 402. 카카오톡 PC 버전 실행 시 개발자 컴퓨터에서 Themida 오류 나는 문제 - 두 번째 이야기
1561정성태1/1/201443951오류 유형: 200. 카카오톡 PC 버전 실행 시 개발자 컴퓨터에서 Themida 오류 나는 문제 [2]
1560정성태1/1/201422486오류 유형: 199. Hyper-V - Checkpoint 생성 오류
1559정성태12/30/201325811.NET Framework: 401. windbg에서 확인해 보는 관리 힙의 인스턴스 구조 [2]
1558정성태12/29/201335456.NET Framework: 400. 눈으로 확인하는 LayoutKind 옵션 효과 [2]파일 다운로드1
1557정성태12/27/201324363.NET Framework: 399. LayoutKind 옵션에 대해 [2]
1556정성태12/27/201344663개발 환경 구성: 208. IIS + Node.js 환경 구성 [8]
1555정성태12/27/201331170개발 환경 구성: 207. IIS의 80 포트를 공유하는 응용 프로그램 만드는 방법 [1]
1554정성태12/26/201336526Windows: 78. 마음에 드는 윈도우 8.1 태블릿 - 델 베뉴 8 프로 5830 [4]
1553정성태12/26/201323606개발 환경 구성: 206. JNBridgePro와 한글 인코딩 문제파일 다운로드1
1552정성태12/25/201328839개발 환경 구성: 205. JNBridgePro를 이용해 C#에서 Java메서드 호출 테스트파일 다운로드1
1551정성태12/24/201323999.NET Framework: 398. tech-days 미니 토요세미나 - 3회 C#편 PPT 자료파일 다운로드1
1550정성태12/13/201326390Windows: 77. Windows 8 - 잠시 사용을 안하는 경우 화면 잠김 상태로 빠지는 문제
1549정성태12/13/201329958VC++: 73. IIS - ISAPI 필터 제작하는 방법 [2]
1548정성태12/10/201322498오류 유형: 198. C# - 제네릭 covariance/contravariance 사용할 때 컴파일 오류가 발생한다면?
1547정성태12/10/201332725.NET Framework: 397. C# - OCX 컨트롤에 구현된 메서드에 배열을 in, out으로 전달하는 방법파일 다운로드2
1546정성태11/28/201326093.NET Framework: 396. C# - 프로퍼티로 정의하면 필드보다 느릴까요? - windbg / ollydbg [3]
1545정성태11/28/201329957.NET Framework: 395. C# - 프로퍼티로 정의하면 필드보다 느릴까요? [3]
1544정성태11/27/201326529개발 환경 구성: 204. Visual Studio Online "Monaco" 서비스와 github 연동
1543정성태11/27/201331236오류 유형: 197. error MSB8008: Specified platform toolset (v120) is not installed or invalid. [1]
1542정성태11/27/201336894오류 유형: 196. The procedure entry point InitializeCriticalSectionEx could not be located in the dynamic link library KERNEL32.dll
1541정성태11/22/201338154.NET Framework: 394. async/await 사용 시 hang 문제가 발생하는 경우 [7]파일 다운로드1
1540정성태11/20/201326431개발 환경 구성: 203. Azure - WEB SITES 서비스 소개 [4]
1539정성태11/19/201330427VS.NET IDE: 83. 형상 관리 서버 운영을 대신해 주는 Visual Studio 온라인 서비스
1538정성태11/19/201331303오류 유형: 195. 웹 사이트의 모든 정적 컨텐츠 요청에 대해 "Internal Server Error" 응답
... 136  137  138  139  140  [141]  142  143  144  145  146  147  148  149  150  ...