C# 비동기 디컴파일링 해보기

코딩소녀·2024년 1월 16일
2
post-thumbnail

안녕 일기장아!

이번엔 async 메서드를 선언하는 것 만으로도 불필요한 객체가 생성된다 해서 실험해보려고 해!
아예 디컴파일링을 해서 async 로 선언되었을 때와 아닐 때를 비교해 볼거야.

뜯기전에 라이선스 확인

원래 남이 작성한 프로그램을 디컴파일해서 뜯어보는건 불법이지만 어째서인지 ILSpy는 Mircosoft 공식 문서에도 등장하니 문제 없을것같아!

그리고 라이선스도 MIT Apache2 이군 이로써 완전한 확인이 완료되었군

ILSpy 설치

우선 깃허브에서 나한테 맞는 버전으로 다운받고 걔를 application 폴더로 이동시켰어.

gui로 하고싶어서 ilspy+avalonia 를 선택했어! 딱히 cli로 디컴파일 할 일이 앞으로 없을것같아서.

예시코드 준비

async 있는 버전

public class Program{
	public static async Task Main(string[] args)
	{
		
	}
}

async 없는 버전

public class Program{
	public static Task Main(string[] args)
	{
		return Task.CompletedTask;
	}
}

이 두개를 비교하면 완전 확실히 알 수 있겠지 !




디컴파일 과정

빌드하고
(아 정렬 못하겠다 너무 어려워 html 프로그래밍...)
(정렬은 안 중요하니 아니니 그냥 냅둘게 ..)

오픈하면

이렇게 디컴파일된 파일이나와!
(상단에서 C# 을 IL 로 바꾸면 중간 언어로 볼 수 있지만 나는 그냥 C# 으로 보도록 할게 !)





디컴파일 결과물 비교

async를 쓴 경우

async를 안쓴 경우

헐 ~ 정말로 가벼워졌잖아?
async를 쓰기만 해도 비동기 상태 머신을 생성해 버리네!
오하려 async를 쓴 쪽이 코드가 한 줄이 더 길었는데 사실은 더 가벼운 코드였어!
앞으로 언제 async로 바뀔지 모른다고 미리 async 함수로 만들어 놓거나 메서드 이름 통일한다고 async를 미리 붙여놓는 행동은 하지 말아야겠어!




해석

public static global::System. Threading. Tasks. Task Main(string|] args)
{
    <Main>d_0 <Main>d = new <Main>d_0); 
    // Main메서드에서 사용할 상태 머신 <Main>d_0 생성하여 변수 <Main>d_에 대입
    
    <Main>dOt_builder = AsyncTaskMethodBuilder.Create(); 
    // AsyncTaskMethodBuilder를 생성하는 static Method Create 호출
    
    <Main>dargs = args;
    // 입력값 로드
    
    <Main>d_.<>1_state = -1;
    // 비동기 상태머신의 상태를 -1로 설정
    // 이는 비동기가 아직 시작되이 않았음을 의미
    
    ((AsyncTaskMethodBuilder) (ref <Main>d_.<>t_builder)).Start<<Main>d_0>(ref <Main>d_);
    // 첫 줄에서 생성한 비동기 상태 머신 <Main>d_ 시작!
    
    return ((AsyncTaskMethodBuilder)(ref <Main>d_.<>t_builder)).get_Task();
    // AsyncTaskMethodBuilder 의 작업을 완료하고 해당 작업의 Task 반환
}

아쉬우니 디컴파일 코드도 해석해봤어!
오늘의 일기 끝!

profile
game server programmer / indie game develop team leader

2개의 댓글

comment-user-thumbnail
2024년 1월 16일

async를 붙여버리면, 그 함수 자체가 비동기로 취급이 되어서 상태머신을 따로 준비하네요!!
비동기가 전혀 필요없으면 async를 빼는 버릇을 들여놔야겠네요!!

1개의 답글