목록전체 글 (157)
Coding Memo
조건부 컴파일 심볼 정의는 파일의 첫줄에 해야한다. #define WINDOWS // ... #if WINDOWS //... #else //... #endif 조건부 컴파일 심볼이 하나의 파일에만 사용되면 간단히 위의 예시처럼 하면 된다. 만약, 저 심볼을 하나의 파일에서가 아니라, 다수의 파일에 적용해야하는 경우가 있다. 예를 들어, 조건부 컴파일 디렉티브로 플랫폼 별 코드를 작성해 놓았는데, 이런 코드가 하나의 파일에서가 아니라 프로젝트의 다수의 파일에 각각 다 심볼이 정의가 되어있을 때가 그런 경우다. 이 경우에는 빌드를 A로 하고 싶으면 심볼이 들어가 있는 모든 파일에 '#define A'가 들어가 있는지 다 확인해야한다. 그 반대로 A가 아닌 빌드를 원한다면 '#define A'가 모두 주석 처..
.NET Framework 1.0 ~ 4.8 .NET Core 1.0 ~ 3.1 .NET 5 이후 C# Version 1.0 ~ 7.3 7.0 ~ 8.0 9.0 ~ 문서에 나와있는 테이블 참고: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version C# language versioning - C# Guide Learn about how the C# language version is determined based on your project and the reasons behind that choice. Learn how to override the default manually. learn..
공통적으로 Microsoft에서 개발한 프레임워크로, 다양한 종류의 어플리케이션을 개발하고 실행하는 기술을 제공해준다. 개발된 순서 .NET Framework -> .NET Core -> .NET (5.0, 6.0, 7.0 ...) .NET Framework 주로 Windows에서 실행되는 프로그램을 개발하기 위해 사용되는 프레임 워크이다. 초기에 개발되고 사용되었고 .NET Framework의 한계점과 개선을 위해서 이후에는 .NET Core가 등장하였다. 1. Windows Desktop, ASP.NET 웹, Windows 서비스 등의 개발에 활용된다. 2. CLR (Common Language Runtime): Java의 JVM과 비슷한 역할로, .NET Framework의 실행 환경으로, 코드 실..
문제 서버 코어를 만들고 빌드를 하여 dll 파일을 생성했다. 이 dll 파일을 Unity에서 그대로 사용하려고 넣어서 컴파일을 했다. 물론 문제가 없었다. 하지만, 서버 코어에 있는 추상 클래스를 상속받아서 클래스를 하나 작성하려고 했는데 참 보기에는 어이없는 에러가 나타났다. CS0115: 재정의할 적절한 메서드를 찾을 수 없습니다. CS0534: 상속된 추상 맴버를 구현하지 않습니다. CS0115는 override 키워드가 적절하게 사용되지 않았을 때 (재정의할 메서드를 찾지 못했을 때) 나타나는 오류이고, CS0534는 추상 클래스를 상속 받았을 때, 반드시 구현해야 하는 맴버를 구현하지 않았을 때 나타나는 에러이다. 그래서 내가 구현을 안했을까? 난 구현했는데 계속 에러가 나타난다! 좀 더 간단..
Serilog는 멀티스레드 환경에서 별도 lock 컨트롤 없어도 괜찮은지 확인해보려고 한다. (기본적으로 Serilog는 thread-safe 하다고 한다.) 10개의 쓰레드 생성 각 쓰레드 마다 1000개의 로그 기록 => 총 n값이 10000까지 출력이 되어야 하고 n 값이 중복되서는 안된다. 다음 함수를 쓰레드로 실행시킬 것이다. n은 static으로 선언해서 별도의 lock 처리 없이 Information (및 Verbose, Debug, Error, Fatal)에서 ++n이 잘 실행되는지도 확인해보겠다. 추가적으로 운좋게(?) 경합이 일어나지 않아 예상대로 출력될 수도 있으니 3번씩은 실행시켜보았다. static int n = 0; static void Thread1() { for (int i ..
lock과 spinlock은 모두 멀티스레드 환경에서 공유 자원을 컨트롤하기 위한 동기화 메커니즘이다. 한 스레드가 접근 중일 때는 다른 스레드들은 대기하게 된다. 그렇다면 각각 어떤 특징이 있고, 어떤 상황에서 둘 중 무엇을 사용해야 더 성능면에서 유리하게 사용할 수 있을지 알아보았다. 대기 방식 - lock: 락을 얻을 때까지 대기를 하고, 대기하는 동안 CPU 자원을 사용하지 않음 - spinlock: busy-waiting 방식으로 다른 쓰레드가 락을 해제할 때까지 계속 루프를 돌면서 기다리고 이 대기 동안에 CPU를 계속 사용함 이 외에는 크게 의미 있는 차이가 없는 것 같다. lock 방식은 CPU 자원을 많이 사용하지 않지만 lock을 얻고 해제하는데 다소 자원이 들어갈 수 있다. 반면에 s..
멀티 쓰레드 환경에서는 여러 쓰레드가 한번에 어떤 공유 자원(전역 변수, 맴버 변수 등등)에 접근하고 수정하려고 하면 매우 큰 문제가 발생할 수도 있다. 아래 코드의 실행 결과를 예상해보자. class Program { static int n = 0; static void Thread1() { for (int i=0; i
구글에서 제공하는 프로토버퍼를 이용해 서버와 클라이언트간 패킷을 주고받는 시나리오를 계획했다. 서버와 클라이언트 간 전송 시에는 byte[]라는 배열로 주고 받게 되는데, 이 배열을 다시 어떤 객체로 파싱하는 과정이 필요하다. CustomBuffer (직접 직렬화한 버퍼)를 사용하였을 때는 버퍼의 헤더를 추가하여, 버퍼의 맨앞에 2바이트 타입을 추가하고 그 값으로 전체 패킷의 길이를 넣었고 두번째 2바이트 값으로 해당 패킷의 원래 객체 타입을 정의해서 넣었었다. 아래의 구조와 같이 직렬화하는 버퍼를 CustomBuffer라고 하겠다. 파싱할 때는, 처음 2바이트를 읽어서 단위 패킷의 범위를 정한다. 그 다음으로 2바이트를 읽어서 Body에 있는 데이터를 어떤 객체로 역직렬화할 건지 알아낸다. 마지막으로,..