C#/수업과제

0329_복습 // Thread

minquu 2021. 3. 30. 00:24
반응형

-Thread 생성 및 실행

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace study12
{
    public class App
    {
        public App()
        {
            Console.WriteLine("App");
            //스레드 변수 선언
            Thread t;

            //ThreadStart대리자 인스턴스화
            ThreadStart ts = new ThreadStart(() => {
                for (int i = 0; i < 10; i++) {
                    Console.WriteLine("Hello~!");
                    Thread.Sleep(500);
                }
            });
            //스레드 인스턴스화
            t = new Thread(ts);
            //스레드 시작
            t.Start();
            //스레드 인스턴스화
            Thread t2 = new Thread(new ThreadStart(this.Hi));
            //스레드 시작
            t2.Start();

        }
        public void Hi()
        {
            for (int i = 0; i < 10; i++) {
                Console.WriteLine("Hi");
                Thread.Sleep(500);
            }
        }
    }
}

 

 

-Thread (Abort _ 중지)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace study12
{
    public class App
    {
        public App()
        {
            Thread t = new Thread(new ThreadStart(this.TestThread));
            t.Start();

            //3초 뒤에
            Thread.Sleep(3000);
            t.Abort("Information from Main");
        }
        private void TestThread()
        {
            try
            {
                while (true)
                {
                    Console.WriteLine("Thread is running...");
                    Thread.Sleep(1000);
                }
            }
            catch (ThreadAbortException abortExcaption) {
                Console.WriteLine((string)abortExcaption.ExceptionState);
            }
        }
    }

abort 상태에서는 스레드가 중지되서 다른 상태를 못 먹인다.

 

-Thread 상태 들

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace study12
{
    public class App
    {
        Thread thread1;
        Thread thread2;
        public App()
        {
            thread1 = new Thread(() =>{
                //Running : 스레드 시작후 동작 상태
                Console.WriteLine(thread1.ThreadState);
                Thread.Sleep(100);
                thread1.Abort();
                Thread.Sleep(100);
                thread1.Join();
            });
            thread1.Name = "Thread1";
            //Unsatared : 스레드 생성후 Start 되기 전 상태
            Console.WriteLine(thread1.ThreadState);
            thread1.Start();
            thread2 = new Thread(() =>{
                while (true) {
                    Thread.Sleep(1000);
                    //waitSleepJoin : 블록상태, Join, Monitor Enter, Sleep 일때 되는 상태
                    Console.WriteLine(thread1.ThreadState);
                    //Stopped : Abort 메서드 호출시 되는 상태 (중지된 스레드의 상태.)
                }
            });
            thread2.Start();
        }
        
    }
}

 

 

-Task 클래스
Task클래스는 값을 반환 하지 않고 비동기적으로 실행 되는 단일 작업을 나타냅니다.
비동기 작업을 나타냅니다. // 자원 불러오기, 파일 수신, 서버 송신 등등에 자주 사용하게 된다. 비동기작업을
결국 Task 객체를 만드는건 스레드를 만드는 것이다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace study12
{
    public class App
    {
        public App()
        {
            Run();
        }
        public async void Run()
        {
            Task<Toast> toastTask = MakeToast(2); //일을 만든다.
            Task<Egg> eggTask = MakeEggs(); //일을 만든다.
            eggTask.Wait();

            Task.WaitAll(new Task[] { toastTask, eggTask });    //모든일이 완료 될때까지 대기

            var arr = new Task[] { toastTask, eggTask };    //일목록을 만들고 
            var idx = Task.WaitAny(arr);    //목록중 어떤거든 완료었다면 목로의 index를 반환 
            Console.WriteLine("idx: {0}", idx); //완료된 목록의 index출력 

            //토스트를 만들어 배열에 담고 그결과를 출력한다 
            Toast[] toasts = await Task.FromResult(Enumerable.Range(1, 5).Select(x => new Toast()).ToArray());
            foreach (var toast in toasts)
            {
                Console.WriteLine(toast);
            }

        }
        private async Task<Egg> MakeEggs()
        {
            Console.WriteLine("계란을 삶습니다.");
            await Task.Delay(2000);
            Console.WriteLine("달걀이 다 삶아 졌습니다.");
            return new Egg();
        }
        private async Task<Toast> MakeToast(int num) {
            for (int i = 0; i < num; i++) {
                Console.WriteLine("빵을 넣었습니다.");
            }
            await Task.Delay(2000); // 2초 대기
            Console.WriteLine("빵이 탔습니다.");
            await Task.Delay(1000); // 똑같이 2초 대기 
            Console.WriteLine("빵을 꺼냈습니다.");
            return new Toast();
        }
        
    }
    public class Toast { 
    }
    public class Egg { 
    
    }
}

 

 

살펴봐야할 키워드

 

async  // 비동기성을 만들기 위해서 제한자 뒤에 붙여줘야하는 키워드

await  // await 연산자는 피연산자가 나타내는 비동기 작업이 완료될 때까지 바깥쪽 비동기 메서드의 평가를 일시 중단합니다. 비동기 작업이 완료되면 await 연산자는 작업 결과를 반환합니다(있는 경우).

 

 async  await 키워드를 사용하여 일련의 비동기 명령이 포함된 코드를 쉽게 추론

 

WaitAll //  모든일이 완료 될 때까지 대기

FromResult // Task를 배열로 만든다.

 

-----

Task 연습 //  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace study12
{
    public class Egg {
        public string desc;
        public Egg(string desc) {
            this.desc = desc;
        }
    }
    public class App
    {
        public App()
        {
            Task<Egg> taskEgg = this.CookEgg(new Egg("생달걀"));
            taskEgg.Wait();
            Console.WriteLine(taskEgg.Result.desc);
        }
        private async Task<Egg> CookEgg(Egg egg)
        {
            var boiledEgg = await BoilEgg(egg);
            return await SeasonEgg(boiledEgg);
        }
        private async Task<Egg> BoilEgg(Egg egg)
        {
            Console.WriteLine("달걀을 삶기 시작합니다.");
            await Task.Delay(1000);
            egg.desc = "삶은 달걀";
            Console.WriteLine("달걀이 삶아 졌습니다.");
            return egg;
        }
        private async Task<Egg> SeasonEgg(Egg egg) {
            await Task.Delay(500);
            egg.desc = "양념된 삶은 달걀";
            return egg;
        }
    }
}

 

Task 일 정의 후 Task 사용

메서드에는 async와 await를 사용함

반응형

'C# > 수업과제' 카테고리의 다른 글

0324_ JSON 파일 리스트화  (0) 2021.03.24
0323_ 람다식 연습  (0) 2021.03.24
0322_ delegates 연습  (0) 2021.03.22
0321 _ 현재 본인 판단 표  (0) 2021.03.21
0318_ArrayList, List<T>, Dictionary 예제 연습  (0) 2021.03.19