<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발 공부 블로그</title>
    <link>https://yk-blog.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 14 Jun 2026 17:59:06 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>yk-</managingEditor>
    <item>
      <title>서버와 클라이언트</title>
      <link>https://yk-blog.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷이 동작하기 위해 필요한 최소 컴퓨터 수는?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2대다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1개는 Web Browser, 1개는 Web Server를 띄우고, 두 대의 컴퓨터는 인터넷으로 연결되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Web Server를 띄운 컴퓨터는 &lt;a href=&quot;http://info.cern.ch와&quot;&gt;http://info.cern.ch와&lt;/a&gt; 같은 주소를 가진다. 그리고 하드디스크를 가진다. 이 하드디스크에는 &lt;a href=&quot;http://index.html&quot;&gt;index.html&lt;/a&gt; 파일이 저장되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그래서 Web&amp;nbsp; Browser를 가진 컴퓨터에서 &lt;a href=&quot;http://info.cern.ch/index.html을&quot;&gt;http://info.cern.ch/index.html&lt;/a&gt;에 들어가면?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://info.cern.ch를&quot;&gt;http://info.cern.ch&lt;/a&gt;를 가진 컴퓨터에게 전기 신호를 보낸다. 그 신호 안에는 index.html 파일을 원한다는 내용이 있다. 그럼 info.cern.ch에 해당되는 컴퓨터에 설치된 Web Server 프로그램이 하드 디스크에서 index.html 파일 안에 담겨있는 코드가 Web Browser를 가진 컴퓨터에게 전기적 신호로 변환해 전달한다. 그럼 Web Browser가 코드를 읽어서 화면에 표시하면 웹사이트가 보여지고 웹이 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Web Browser와 Web Server의 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Web Browser는 요청(request)을 하고, Web Server는 응답(response)을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 관계에 따라, 각각을 고객(Client)/서비스 제공자(Server)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버로 웹 브라우저를 띄우는법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. web server - 자신의 컴퓨터에 웹 서버를 직접 깔아서 사용하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. web hosting - 대행 업체한테 서버를 맡기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt; 출처 &amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=yBPyzaccbkc&amp;amp;list=PLuHgQVnccGMDZP7FJ_ZsUrdCGH68ppvPb&amp;amp;index=17&quot;&gt;WEB1 - 17. 인터넷을 여는 열쇠 : 서버와 클라이언트&lt;/a&gt;&lt;/p&gt;</description>
      <category>WEB</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/63</guid>
      <comments>https://yk-blog.tistory.com/63#entry63comment</comments>
      <pubDate>Fri, 1 May 2026 21:14:23 +0900</pubDate>
    </item>
    <item>
      <title>Unity에서의 에셋 관리와 Addressables</title>
      <link>https://yk-blog.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;에셋 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 개발 초기에는 Resources.LoadAsync와 같이 많이 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 방법은 빌드 시간이 증가되고 에셋 관리가 힘듦&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 진행이 어느정도 되면 AssetBundle을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AssetBudle.LoadFromFileAysnc&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 번들을 로컬 디스크에 저장해서 에셋을 불러오는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 런칭에 가까워지면 서버에서 다운받도록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UnityWebRequest.GetAssetBundle(bundleUrl); 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번들을 서버에서 가져와서 디스크 저장하고, 디스크에서 다시 로드하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 방법은 dependency 처리가 되어있지 않아서 사용하면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에셋은 서로 dependency가 있다. ex) 오브젝트1이 다른 머티리얼, 셰이더를 참조한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에셋번들은 다른 에셋번들에 종속성이 걸려있을 수 있다. 근데 이 종속관계를 무시하고 불러오면 메모리에 에셋이 중복되게 올라갈 수 있다. 그래서 dependency를 고려해서 불러오는 코드를 짜야한다.(6:48)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 단점을 보완한 게 Addressables이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 스크립트에서 public AssetReference name1;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 하이어라키에서 에셋을 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 name1.InstantiateAsync()로 비동기로 로드해서 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Analyze 기능에서 에셋의 dependecy를 확인할 수 있고, 정적분석(코드분석)을 해서 dependecy가 어떤 식으로 걸려있는지 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 Addressables는 모바일에서는 많이 사용되고, 또 DLC에 많이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 영상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3f2XjEGDZ2s&amp;amp;t=2s&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=3f2XjEGDZ2s&amp;amp;t=2s&lt;/a&gt;&lt;/p&gt;</description>
      <category>Unity/기술</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/62</guid>
      <comments>https://yk-blog.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 5 Jan 2026 12:56:30 +0900</pubDate>
    </item>
    <item>
      <title>[Web Server] HTTP 서버통신 및 API 사용방법</title>
      <link>https://yk-blog.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;* HTTP 통신이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기적인 통신이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 온라인게임처럼 여러명이 실시간 소통하는 서버가 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 pc에서 필요한 정보만 웹서버에 요청하면, 웹서버에서 응답을 보내주는 비동기적인 서버통신이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 유니티에서 HTTP 통신을 하는 방법은 2가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. WWW 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. UnityWebRequest 방식 =&amp;gt; 최신 방법이고, WWW 방식에서 사용할 수 있는 기능을 모두 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* HTTP 통신을 할 때 주의해야할 사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 코루틴을 사용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;: 코루틴을 사용하지 않으면 요청을 보내고 처리하고 응답이 오는데까지 걸리는 시간동안 프로그램이 멈춘다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. using문을 사용하는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;: 스크립트 상단에 네임스페이스 추가할 때 쓰는 using문 말하는 거 아니고, 스크립트 중간에 있는 것을 말하는 거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹서버를 통해 다양한 리소스가 왔다갔다 할텐데, using문을 사용하면 필요없어질 때 자동으로 dispose해줘서 리소스 관리에 용이하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 사용예시&lt;/p&gt;
&lt;pre id=&quot;code_1760525358187&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class WebRequest : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(UnityWebRequestGet());
    }

    IEnumerator UnityWebRequestGet()
    {
        string url = &quot;https://api.neople.co.kr/df/servers?apikey=VDAVlX4BJrUp6Mj7gXkpDETbhTuUuI7V&quot;;
     
        UnityWebRequest www = UnityWebRequest.Get(url);

        yield return www.SendWebRequest();

        if(www.result != UnityWebRequest.Result.Success)
        {
            Debug.Log(www.error);
        }
        else
        {
            // Show results as text
            Debug.Log(www.downloadHandler.text);
            // Or retrieve results as binary data
            byte[] results = www.downloadHandler.data;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=GxCf1SsLVB4&quot;&gt;[유니티] HTTP 서버통신 및 API 사용방법&lt;/a&gt;&lt;/p&gt;</description>
      <category>Unity/Web Server</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/61</guid>
      <comments>https://yk-blog.tistory.com/61#entry61comment</comments>
      <pubDate>Wed, 15 Oct 2025 19:50:18 +0900</pubDate>
    </item>
    <item>
      <title>[Web Server] 섹션 3. 고급 C# 문법 - 12. LINQ #2</title>
      <link>https://yk-blog.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;from 중첩해서 사용하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; foreach를 2번 쓴 것과 같은 효과!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1759995967401&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// from 2번 쓰기
var playerItems = from player in _players
                  from item in player.Items
                  where item &amp;lt; 30
                  select new { player, item };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;grouping&lt;/p&gt;
&lt;pre id=&quot;code_1759995991043&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// grouping
var playersByLevel = from player in _players
                     group player by player.Level into levelGroup
                     orderby levelGroup.Key
                     select new { levelGroup.Key, Players = levelGroup };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;join&lt;/p&gt;
&lt;pre id=&quot;code_1759996019353&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// outer join(외부 조인)
List&amp;lt;int&amp;gt; levels = new List&amp;lt;int&amp;gt;() { 1, 5, 9 };

var playerLevels = from player in _players
                   join level in levels
                   on player.Level equals level
                   select player;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LINQ 표준 연산자&lt;/p&gt;
&lt;pre id=&quot;code_1759996047471&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// LINQ 표준 연산자
var players2 = from player in _players
               where player.ClassType == ClassType.Knight &amp;amp;&amp;amp; player.Level &amp;gt;= 50
               orderby player.Level ascending
               select player;

// 위와 같은 표현. 이 버전이 세부 기능이 더 많음
var players3 = _players
    .Where(p =&amp;gt; p.ClassType == ClassType.Knight &amp;amp;&amp;amp; p.Level &amp;gt;= 50)
    .OrderBy(p =&amp;gt; p.Level)
    .Select(p =&amp;gt; p);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2가지 버전이 있는데, 위 버전에 있는데 아래 버전에 없는 기능이 있기도 하고, 그 반대의 경우도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 중에는 아래 버전이 더 기능이 많아서, 많은 기능을 쓰고싶으면 아래 버전을 사용하면 된다.&lt;/p&gt;</description>
      <category>Unity/Web Server</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/60</guid>
      <comments>https://yk-blog.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 9 Oct 2025 16:48:28 +0900</pubDate>
    </item>
    <item>
      <title>[Web Server] 섹션 3. 고급 C# 문법 - 12. LINQ #1</title>
      <link>https://yk-blog.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 가공할 때 유용하게 쓸 수 있는 문법이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL 문법과 비슷하고 가독성이 좋아 기능을 쉽게 파악할 수 있다는 것이 장점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 유니티에서 LINQ 쓰면 오류날 수도 있어서...(특히 ios) 별로 추천하진 않는다고 한다...(초창기에 그랬다고 함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 LINQ를 기반으로 하는 기술들이 많아서, 공부할 가치가 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1759045917014&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    public enum ClassType
    {
        Knight,
        Archer,
        Mage,
    }

    public class Player
    {
        public ClassType ClassType { get; set; }
        public int Level { get; set; }
        public int Hp { get; set; }
        public int Attack { get; set; }
    }

    class Program
    {
        static List&amp;lt;Player&amp;gt; _players = new List&amp;lt;Player&amp;gt;();

        static async Task Main(string[] args)
        {
            Random random = new Random();

            for (int i = 0; i &amp;lt; 100; i++)
            {
                ClassType classType = (ClassType)random.Next(0, 3);
                int level = random.Next(1, 100);
                int hp = random.Next(100, 1000);
                int attack = random.Next(5, 50);
                Player player = new Player
                {
                    ClassType = classType,
                    Level = level,
                    Hp = hp,
                    Attack = attack
                };
                _players.Add(player);
            }


            // 레벨이 50이상인 Knight만 추려내서
            // 레벨을 오름차순으로 순서로 정렬
            // 기존 방법
            List&amp;lt;Player&amp;gt; players = GetHighLevelKnights();
            foreach (Player player in players)
            {
                Console.WriteLine($&quot;ClassType : {player.ClassType}, Level : {player.Level}, Hp : {player.Hp}, Attack : {player.Attack}&quot;);
            }

            Console.WriteLine(&quot;===================================&quot;);

            // LINQ 사용 방법
            List&amp;lt;Player&amp;gt; linqPlayers = GetHighLevelKnightsByLinq();
            foreach (Player player in linqPlayers)
            {
                Console.WriteLine($&quot;ClassType : {player.ClassType}, Level : {player.Level}, Hp : {player.Hp}, Attack : {player.Attack}&quot;);
            }
        }


        // 기존 방법
        static public List&amp;lt;Player&amp;gt; GetHighLevelKnights()
        {
            List&amp;lt;Player&amp;gt; players = new List&amp;lt;Player&amp;gt;();
            foreach (var player in _players)
            {
                if (player.ClassType != ClassType.Knight)
                    continue;

                if (player.Level &amp;lt; 50)
                    continue;

                players.Add(player);
            }

            players.Sort((p1, p2) =&amp;gt; p1.Level.CompareTo(p2.Level));

            return players;
        }

        // LINQ 사용 방법
        static public List&amp;lt;Player&amp;gt; GetHighLevelKnightsByLinq()
        {
            // from : foreach 역할
            // where : 필터 역할(조건에 부합하는 데이터만 걸러냄)
            // orderby : 정렬 역할(ascending / descending)
            // select : 최종 결과 추출. 가공해서 추출할지도 결정 가능. ex) player.Hp
            //          Anonymous Type 으로 추출 가능. ex) new { Hp = player.Hp, Level = player.Level * 2 }

            var players = from player in _players
                          where player.ClassType == ClassType.Knight &amp;amp;&amp;amp; player.Level &amp;gt;= 50
                          orderby player.Level ascending
                          select player;
            return players.ToList();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part6&quot;&gt;[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part6: 웹 서버 강의 | Rookiss - 인프런&lt;/a&gt;&lt;/p&gt;</description>
      <category>Unity/Web Server</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/59</guid>
      <comments>https://yk-blog.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 28 Sep 2025 16:55:26 +0900</pubDate>
    </item>
    <item>
      <title>[Web Server] 섹션 3. 고급 C# 문법 - 11. Async, Await</title>
      <link>https://yk-blog.tistory.com/58</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;async 이름만 봐도 비동기 프로그래밍 같지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기라고 꼭 멀티쓰레드는 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동기와 다르게 하나가 끝날 때까지 기다리지 않아도 된다는 의미에서 비동기이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼭 멀티쓰레드 환경에서 실행되어야 한다는 보장은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 한 스레드 안에서 일을 분배해서 함(약간 코루틴 느낌~)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 coroutine은 싱글 스레드에서 동작한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Task란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일감을 만들어서 보내준다~ 대충 이런 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756027538623&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    class Program
    {
        static Task Test()
        {
            Console.WriteLine(&quot;Task start&quot;);
            Task t = Task.Delay(3000);
            return t;
        }

        static void Main(string[] args)
        {
            Task t = Test();

            Console.WriteLine(&quot;while start&quot;);
            while (true)
            {

            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task start를 출력하고 바로 while start가 찍힌다.(3초 기다리지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start가 출력문이 찍히는 건 3초 기다리는 거와는 별개의 문제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 기다리게 하고싶다면 아래와 같이 코드를 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756027856492&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    class Program
    {
        static Task Test()
        {
            Console.WriteLine(&quot;Task start&quot;);
            Task t = Task.Delay(3000);
            return t;
        }

        static void Main(string[] args)
        {
            Task t = Test();
            // 구간1
            t.Wait();
            // 구간2

            Console.WriteLine(&quot;while start&quot;);
            while (true)
            {

            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3초 뒤)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 알 수 있는건,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Task의 종료와 상관없이 실행시킬 수 있는 구간1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Task가 종료된 뒤 실행시킬 수 있는 구간2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요에 따라 두 개의 구간을 사용할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;t.Wait()이 함수 안으로 들어가면 어떻게 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756028912510&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    class Program
    {
        static void TestAsync()
        {
            Console.WriteLine(&quot;Task Async start&quot;);
            Task t = Task.Delay(3000); // 복잡한 작업 (ex. DB나 파일 작업)

            t.Wait();
            Console.WriteLine(&quot;Task Async end&quot;);
        }

        static void Main(string[] args)
        {
            TestAsync();

            Console.WriteLine(&quot;while start&quot;);
            while (true)
            {

            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3초 뒤)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async end&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 코드의 문제는,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래 걸리는 복잡한 작업(Task.Delay()부분)이 끝날때까지 대기를 해야하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부로 빠져나가지 못해, 다음 부분을 실행하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것보단 기다리는 동안 다른 작업을 위해 코드 제어권을 넘겨주는 방식이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서는 await를 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756029417427&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    class Program
    {
        static async void TestAsync()
        {
            Console.WriteLine(&quot;Task Async start&quot;);
            
            Task t = Task.Delay(3000);
            await t;
            // 위 두 줄을 아래와 같이 한 줄로 쓸 수 있음
            // await Task.Delay(3000);
            
            Console.WriteLine(&quot;Task Async end&quot;);
            
            
            
        }

        static void Main(string[] args)
        {
            TestAsync();

            Console.WriteLine(&quot;while start&quot;);
            while (true)
            {

            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력 결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(while start 출력 약 3초 후)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async end&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 여기서...스레드가 while(true) 무한루프에 빠져있진 않나? 싶은데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Console.WriteLine(&quot;Task Async end&quot;); 라인을 디버깅해보면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓰레드가 나뉘어져서 Task Async end를 출력하는 스레드 / while 무한 루프에 빠져있는 스레드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 2개로 나뉘어져 있는 걸 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경우에 따라 이렇게 멀티 쓰레드로 잡힐 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main에 Async Await가 있으면 어떻게 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1757241811267&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading.Tasks;
using System;

namespace TaskPractice
{
    class Program
    {
        static async Task TestAsync()
        {
            Console.WriteLine(&quot;Task Async start&quot;);
            await Task.Delay(3000);
            Console.WriteLine(&quot;Task Async end&quot;);
        }

        static async Task Main(string[] args)
        {
            await TestAsync();

            Console.WriteLine(&quot;while start&quot;);
            while (true)
            {

            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3초 뒤)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task Async end&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while start&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task&amp;lt;int&amp;gt;와 같이 반환형을 적어 반환값을 return할 수도 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* async await를 쓸 때의 장점(그냥 delay할 때에 비해)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 코드 흐름을 넘겨 끝까지 기다리지 않고 다른 일을 할 수 있게 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 부분 블럭마다 할 일을 줄 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) await 이전 / await 이후 ... 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part6&quot;&gt;[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part6: 웹 서버 강의 | Rookiss - 인프런&lt;/a&gt;&lt;/p&gt;</description>
      <category>Unity/Web Server</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/58</guid>
      <comments>https://yk-blog.tistory.com/58#entry58comment</comments>
      <pubDate>Sun, 7 Sep 2025 20:05:34 +0900</pubDate>
    </item>
    <item>
      <title>[Web Server] 섹션 2. 웹 기초 - 3. 환경 설정</title>
      <link>https://yk-blog.tistory.com/57</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;OSI 7계층에서...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;1177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LkjpM/btsP5IOsA3k/xjldWFOCwRgKrordEkknU0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LkjpM/btsP5IOsA3k/xjldWFOCwRgKrordEkknU0/img.webp&quot; data-alt=&quot;출처 : 7 OSI Layer: The Building Blocks of Networking - Telkom University Jakarta&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LkjpM/btsP5IOsA3k/xjldWFOCwRgKrordEkknU0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLkjpM%2FbtsP5IOsA3k%2FxjldWFOCwRgKrordEkknU0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;604&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;1177&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 7 OSI Layer: The Building Blocks of Networking - Telkom University Jakarta&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Application layer에서 유저인터페이스, &lt;b&gt;HTTP&lt;/b&gt;, FTP, DNS 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transport layer에서 전송 확인 / 오류 해결, &lt;b&gt;TCP, UDP&lt;/b&gt;가 전달됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP는 내부적으로 TCP, UDP로 만들어져 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임서버는 보통 TCP 서버로 만들고 웹서버는 HTTP.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘은 다른 레이어에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Unity/Web Server</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/57</guid>
      <comments>https://yk-blog.tistory.com/57#entry57comment</comments>
      <pubDate>Sun, 24 Aug 2025 17:21:24 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] OnBeginDrag 안되는 버그(IBeginDragHandler)</title>
      <link>https://yk-blog.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 해결법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDragHandler도 상속받아서 OnDrag() 함수 구현하면 OnBeginDrag도 동작한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고자료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://discussions.unity.com/t/ibegindraghandler-not-called-without-eventtrigger-component/568450/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://discussions.unity.com/t/ibegindraghandler-not-called-without-eventtrigger-component/568450/2&lt;/a&gt;&lt;/p&gt;</description>
      <category>Unity/Client</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/56</guid>
      <comments>https://yk-blog.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 14 Aug 2025 12:56:51 +0900</pubDate>
    </item>
    <item>
      <title>[C#] Thread의 상태</title>
      <link>https://yk-blog.tistory.com/55</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 스레드 상태 종류&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvQEwH/btsPQCpn9O6/WhQmYVcVPEVT02lNiZX560/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvQEwH/btsPQCpn9O6/WhQmYVcVPEVT02lNiZX560/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvQEwH/btsPQCpn9O6/WhQmYVcVPEVT02lNiZX560/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvQEwH%2FbtsPQCpn9O6%2FWhQmYVcVPEVT02lNiZX560%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;299&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EjZxV/btsPTlsqEWp/4XW1kwwZdHR2kbMoJYl3AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EjZxV/btsPTlsqEWp/4XW1kwwZdHR2kbMoJYl3AK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EjZxV/btsPTlsqEWp/4XW1kwwZdHR2kbMoJYl3AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjZxV%2FbtsPTlsqEWp%2F4XW1kwwZdHR2kbMoJYl3AK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;195&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Unstarted : 스레드 생성 후 Start() 메서드가 실행되기 전(스레드 시작하기 전) 상태&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Running : 스레드가 동작 중인 상태&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qZgH5/btsPR4ryc3m/JWv1gDWHybupqR1NZxK0h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qZgH5/btsPR4ryc3m/JWv1gDWHybupqR1NZxK0h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qZgH5/btsPR4ryc3m/JWv1gDWHybupqR1NZxK0h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqZgH5%2FbtsPR4ryc3m%2FJWv1gDWHybupqR1NZxK0h0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;516&quot; height=&quot;192&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Suspended : 스레드 일시 중지 상태. Thread.Rewume() 메소드 호출까지 대기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ue3M4/btsPSzZjyUu/v8uPipizbletD1UgJ3Oe31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ue3M4/btsPSzZjyUu/v8uPipizbletD1UgJ3Oe31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ue3M4/btsPSzZjyUu/v8uPipizbletD1UgJ3Oe31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUe3M4%2FbtsPSzZjyUu%2Fv8uPipizbletD1UgJ3Oe31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;195&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WaitSleepJoin : 스레드 일시 중지 상태. 특정 조건까지만 대기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;* Thread.Sleep()&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 ms 시간만큼 스레드가 대기하는 것&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;* Thread.Join()&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 스레드가 실행이 끝날 때까지 대기하는 것&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIC6Y9/btsPRrgD9sg/H2HCWG4LPHuCfM2EBIEl40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIC6Y9/btsPRrgD9sg/H2HCWG4LPHuCfM2EBIEl40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIC6Y9/btsPRrgD9sg/H2HCWG4LPHuCfM2EBIEl40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIC6Y9%2FbtsPRrgD9sg%2FH2HCWG4LPHuCfM2EBIEl40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;199&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Aborted : 강제 종료. 보이기에는 바로 종료되어 보이지만 근데 실제로는 바로 종료되는 게 아니라 일정 시간 후에 종료됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMj570/btsPTAbV0UE/J1hd9TaHr1MqubCTqQms0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMj570/btsPTAbV0UE/J1hd9TaHr1MqubCTqQms0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMj570/btsPTAbV0UE/J1hd9TaHr1MqubCTqQms0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMj570%2FbtsPTAbV0UE%2FJ1hd9TaHr1MqubCTqQms0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;201&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포그라운드 스레드가 죽어버리면 해당 프로세스는 꺼진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백그라운드 스레드는 죽어도 프로세스 수명에 영향이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceLODt/btsPSMKIejF/YXW43DcJpsSgzcJS3IDzq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceLODt/btsPSMKIejF/YXW43DcJpsSgzcJS3IDzq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceLODt/btsPSMKIejF/YXW43DcJpsSgzcJS3IDzq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceLODt%2FbtsPSMKIejF%2FYXW43DcJpsSgzcJS3IDzq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;201&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread.Abort()와 다르게 WaitSleepJoin상태가 될 때까지 돌아가다가 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://www.youtube.com/watch?v=QUbULXmNzRA&amp;amp;t=637s&quot;&gt;유니티 C# 고급문법 ThreadState (스레드 상태)&lt;/a&gt;&lt;/p&gt;</description>
      <category>CS/C#</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/55</guid>
      <comments>https://yk-blog.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 13 Aug 2025 23:52:25 +0900</pubDate>
    </item>
    <item>
      <title>[C#] Thread</title>
      <link>https://yk-blog.tistory.com/54</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 프로세스와 스레드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로세스는 반드시 하나 이상의 스레드로 구성되어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 둘 이상의 스레드를 동시에 실행하면 멀티스레드라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 스레드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 운영체제가 CPU에 시간을 할당하는 (일을 시키는) 기본 단위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 운영체제가 명령어를 실행하기 위한 스케줄링 단위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 멀티 스레드의 장점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 동시에 여러 작업을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 데이터 공유가 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 유니티에서 코루틴을 쓰는 이유&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티는 게임 로직 쓰레드(메인 쓰레드) 1개에서만 게임 로직을 짤 수 있다. 스레드를 만들어 사용하면, 그 스레드에서는 유니티의 기능을 사용할 수없다. 그래서 코루틴을 사용해 병렬 처리(하지만 실제로는 동기로 작동)를 구현하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;pre id=&quot;code_1752144541081&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading;
using UnityEngine;

public class ThreadTest : MonoBehaviour
{
    private void Start()
    {
        Thread thread = new Thread(PositionCheck);
        thread.Start();
    }

    private void PositionCheck()
    {
        Debug.Log(transform.position);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 스크립트를 작성하고 플레이해보면 오류가 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ag0lG/btsPdbx3OZZ/Ah9gNU77aiPhXfk1VWpK10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ag0lG/btsPdbx3OZZ/Ah9gNU77aiPhXfk1VWpK10/img.png&quot; data-alt=&quot;UnityException: get_transform은 메인 스레드에서만 호출할 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ag0lG/btsPdbx3OZZ/Ah9gNU77aiPhXfk1VWpK10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAg0lG%2FbtsPdbx3OZZ%2FAh9gNU77aiPhXfk1VWpK10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;898&quot; height=&quot;67&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UnityException: get_transform은 메인 스레드에서만 호출할 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티에서 제공하는 속성들은 메인 스레드에서만 사용할 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 그러면 유니티에서 멀티쓰레드는 어디에 쓰는걸까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능 향상을 위해 유니티 메인 로직과 분리할 수 있으면서 연산이 무거운 것들을 멀티쓰레드로 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면 시간이 오래 걸리는 복잡한 계산(길찾기 알고리즘), 파일 로드, DB, 네트워크 통신에 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 스레드 사용법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread()는 델리게이트를 인자로 받는다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 함수를 인자로 넘김.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매개변수가 없는 경우&lt;/p&gt;
&lt;pre id=&quot;code_1755096196519&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading;
using UnityEngine;

public class ThreadTest : MonoBehaviour
{
	Thread thread;
    private void Start()
    {
        thread = new Thread(Temp);
        thread.Start();
    }

    private void Temp()
    {
        Debug.Log(&quot;스레드 시작&quot;);
        Debug.Log(thread.ThreadState);
        Thread.Sleep(2000); // 2초 동안 스레드 중지
        Debug.Log(&quot;스레드 종료&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매개변수가 있는 경우&lt;/p&gt;
&lt;pre id=&quot;code_1755096591778&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading;
using UnityEngine;

public class ThreadTest : MonoBehaviour
{
	Thread thread;
    private void Start()
    {
        thread = new Thread(new ParameterizedThreadStart(Temp));
        // 델리게이트이므로 아래처럼 작성 가능
        thread = new Thread(Temp);
        thread.Start(10);
    }

    private void Temp(object num)
    {
        Debug.Log(&quot;스레드 시작&quot;);
        Debug.Log(thread.ThreadState);
        Thread.Sleep(2000); // 2초 동안 스레드 중지
        Debug.Log(num);
        Debug.Log(&quot;스레드 종료&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매개변수가 여러개인 경우&lt;/p&gt;
&lt;pre id=&quot;code_1755416690180&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Threading;
using UnityEngine;

public class ThreadTest : MonoBehaviour
{
    public class Param
    {
        public int value1;
        public int value2;
    }

    Thread thread;
    void Start()
    {
        thread = new Thread(Temp);
        Param param = new Param();
        param.value1 = 10;
        param.value2 = 10;
        thread.Start(param);
    }

    void Temp(object num)
    {
        Debug.Log(&quot;스레드 시작&quot;);
        Debug.Log(thread.ThreadState);
        Thread.Sleep(2000);
        Param param = (Param)num;
        Debug.Log(param.value1);
        Debug.Log(param.value2);
        Debug.Log(&quot;스레드 종료&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.youtube.com/watch?v=5a3H11SVylw&quot;&gt;유니티 C# 고급문법 Thread (스레드)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.youtube.com/watch?v=XRC2u9n_tBo&amp;amp;t=416s&quot;&gt;유니티 C# 고급문법 Multi Thread (멀티스레드)&lt;/a&gt;&lt;/p&gt;</description>
      <category>CS/C#</category>
      <author>yk-</author>
      <guid isPermaLink="true">https://yk-blog.tistory.com/54</guid>
      <comments>https://yk-blog.tistory.com/54#entry54comment</comments>
      <pubDate>Wed, 13 Aug 2025 23:52:16 +0900</pubDate>
    </item>
  </channel>
</rss>