[C# 5.0] 비동기 호출

eunjin lee·2022년 12월 21일
0

C# 9.0 프로그래밍

목록 보기
37/50

C# 5.0에는 async와 await 예약어를 이용하여 비동기 호출을 마치 동기 방식처럼 호출하는 코드를 작성할 수 있다.


📝 동기 호출

        static void Main(string[] args)
        {
            SyncPrint();
        }

        static void SyncPrint()
        {
            using (FileStream fs = new FileStream(@"C:\TestWorkspace\fileTest.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                byte[] buf = new byte[fs.Length];

                fs.Read(buf, 0, buf.Length);

                Console.WriteLine("Success");
                string txt = Encoding.UTF8.GetString(buf);
                Console.WriteLine(txt);

                
            }
        }

📝 비동기 호출

        static void Main(string[] args)
        {
            AsyncPrint();
        }
        
        static async void AsyncPrint()
        {
            using (FileStream fs = new FileStream(@"C:\TestWorkspace\fileTest.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                byte[] buf = new byte[fs.Length];

                await fs.ReadAsync(buf, 0, buf.Length);
                string txt = Encoding.UTF8.GetString(buf);
                Console.WriteLine(txt);
            }
        }

async와 await 예약어 덕분에 호출 방식이 달라졌음에도 코드를 작성하는 방식에는 변화가 없다. 두 방식의 차이점을 알아보기 위해 아래의 코드를 실행해보자.

📝 동기와 비동기의 쓰레드 차이

        static void Main(string[] args)
        {
            Console.WriteLine("Before Call : "+ +Thread.CurrentThread.ManagedThreadId);
            //SyncPrint();
            AsyncPrint();
            Console.WriteLine("After Call : " + +Thread.CurrentThread.ManagedThreadId);


        }
        
        static void SyncPrint()
        {
            using (FileStream fs = new FileStream(@"C:\TestWorkspace\fileTest.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                byte[] buf = new byte[fs.Length];

                Console.WriteLine("Before Sync Read : "+Thread.CurrentThread.ManagedThreadId);
                fs.Read(buf, 0, buf.Length);
                Console.WriteLine("After Sync Read : "+Thread.CurrentThread.ManagedThreadId);

                Console.WriteLine("Success");
                string txt = Encoding.UTF8.GetString(buf);
                Console.WriteLine(txt);

                
            }
        }
        
        static async void AsyncPrint()
        {
            using (FileStream fs = new FileStream(@"C:\TestWorkspace\fileTest.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                byte[] buf = new byte[fs.Length];

                Console.WriteLine("Before Sync Read : " + Thread.CurrentThread.ManagedThreadId);
                await fs.ReadAsync(buf, 0, buf.Length);
                Console.WriteLine("After Sync Read : " + Thread.CurrentThread.ManagedThreadId);
                
                Console.WriteLine("Success");
                string txt = Encoding.UTF8.GetString(buf);
                Console.WriteLine(txt);
            }
        }

✅ SyncPrint 호출 시 결과

Before Call : 1
Before Sync Read : 1
After Sync Read : 1
Success
After Call : 1
  • Read를 실행하기 전과 후의 쓰레드가 변하지 않는다.

✅ AsyncPrint 호출 시 결과

Before Call : 1
Before Sync Read : 1
After Call : 1
After Sync Read : 4
Success
  • await 아래의 구문부터는 쓰레드 아이디가 변화하였다. await 이후의 코드는 ReadAsync 작업이 완료된 후 별도의 쓰레드에서 실행되는 것이다.

0개의 댓글