일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- github
- c#
- C++
- Python
- jupyter lab
- c# 윈폼
- gitlab
- jupyter
- 구조체
- 도커
- Algorithm
- Flutter
- 다트 언어
- c# 추상 클래스
- Unity
- HTML
- Data Structure
- C언어 포인터
- dart 언어
- 깃
- 플러터
- C# delegate
- git
- 포인터
- docker
- c# winform
- Houdini
- c언어
- vim
- 유니티
- Today
- Total
목록Programming (313)
nomad-programmer
Form 클래스는 운영체제가 보내는 메시지 중 일부에 대해 이벤트를 구현하고 있다. 가령 사용자가 Form의 인스턴스, 즉 윈도우 위에서 마우스의 왼쪽 버튼을 누르면 WM_LBUTTONDOWN 메시지가 Form 객체로 전달되고, Form 객체는 이에 대해 MouseDown 이벤트를 발생시킨다. Form과 WinForm의 윈도우와 컨트롤 클래스들이 윈도우 메시지를 포장하여 이벤트로 구현해 놓았다. 개발자는 그저 미리 정의되어 있는 이벤트에 이벤트 처리기 메소드를 선언하여 등록해주기만 하면 된다. // 이벤트 처리기 메소드를 선언하고 Form 클래스의 MouseDown 이벤트 등록 class MyForm : Form { // 이벤트 처리기 선언 private void FormMouseDown(object s..
WinForm은 폼 디자이너라는 툴을 제공해서 프로그래머가 그림 그리듯 UI를 만들 수 있게 한다. 이른바 WYSIWYG(What You See Is What You Get) 방식의 개발을 지원하는 것이다. 컨트롤을 윈도우 위에 배치할 때마다 폼 디자이너는 프로그램의 UI를 표시하는 한편, 뒤로는 관련 C# 코드를 자동으로 만들어 준다. 프로퍼티를 변경할 때, 이벤트 처리기를 추가할 때도 자동으로 코드를 수정해준다. C# 코드로 WinForm 윈도우 만들기 Win32 API를 이용하여 윈도우를 만드는 절차 윈도우 클래스를 정의한다(윈도우에 대한 정보를 가지고 있는 구조체). 정의된 윈도우 클래스를 등록한다. 윈도우를 생성한다. 윈도우를 사용자에게 보여준다. 메시지 루프를 돌면서 프로그램을 시작한다. Wi..
Python언어에서의 with문과 똑같은 역할을 한다고 생각하면 된다. using문은 using 블록 내에서 예외가 발생하더라도 Dispose(또는 DisposeAsync)가 호출되도록 한다. try 블록 내부에 개체를 배치한 다음, finally 블록에서 Dispose(또는 DisposeAsync)를 호출해도 동일한 결과를 얻을 수 있다. 실제로 컴파일러는 이 방법으로 using 문을 변환한다. C# 8.0 버전부터 using 문은 IAsyncDisposable 개체의 올바른 사용을 보장한다. using문을 사용하지 않은 코드 예제 using System; using System.IO; namespace CSharpExample { internal class MainApp { static int Mai..

명명 규칙 규칙에 따라 일반적으로 대기 가능한 형식 (예: Task, Task, ValueTask, ValueTask)을 반환하는 메소드에는 "Async"로 끝나는 이름을 사용해야 한다. 비동기 작업을 시작하지만 대기 가능한 형식을 반환하지 않는 메소드는 "Async"로 끝나는 이름을 사용하지 않아야 하지만, "Begin", "Start" 또는 일부 다른 동사로 시작하여 이 메소드가 작업 결과를 반환하거나 예외가 발생하지 않음을 알려야 한다. 여기서 이벤트, 기본 클래스 또는 인터페이스 계약으로 다른 이름을 제안하는 규칙을 무시할 수 있다. 예를 들어, OnButtonClick과 같은 공용 이벤트 처리기의 이름을 변경할 수 없다. 정리하자면, * 반환형이 있는 비동기 메소드의 이름은 접미사로 "Async..
System.Threading.Tasks.Parallel 클래스 이 클래스는 For(), Foreach() 등의 메소드를 제공하여 Task를 이용한 병렬 처리를 더 쉽게 구현할 수 있도록 해준다. void SomeMethod(int i) { Console.WriteLine(i); } // ... Parallel.For(0, 100, SomeMethod); 위 코드에서 Parallel.For() 메소드는 SomeMethod()를 병렬로 호출하면서 0부터 100사이의 정수를 메소드의 매개 변수로 넘긴다. SomeMethod() 메소드를 병렬로 호출할 때 몇 개의 스레드를 사용할지는 Parallel 클래스가 내부적으로 판단하여 최적화한다. 병렬 처리로 소수를 찾는 예제 using System; using Sy..
병렬 처리와 비동기 처리의 차이 병렬 처리와 비동기 처리는 비슷한 용어 같지만 뜻이 엄밀히 다르다. 병렬 처리 : 하나의 작업을 여러 작업자가 나눠서 수행한 뒤 다시 하나의 결과로 만드는 것을 병렬 처리라한다. 비동기 처리 : 작업 A를 시작한 후 A의 결과가 나올 때까지 마냥 대기하는 대신 곧이어 다른 작업 B, C, D, ...를 수행하다가 작업 A가 끝나면 그 때 결과를 받아내는 처리를 말한다. 마이크로소프트는 더 쉽게 비동기 코드를 작성할 수 있도록 하는 도구와 장치를 준비했다. System.Threading.Tasks 네임스페이스의 클래스들과 async 한정자와 await 연산자들이다. .NET 프레임워크 4.0부터 도입된 System.Threading.Tasks 네임스페이스에는 병행성 코드나 ..

저수준 동기화 : Monitor.Wait() 메소드와 Monitor.Pulse() 메소드 lock 키워드 대신 Monitor 클래스를 사용해야 한다면 그건 Enter()와 Exit() 메소드 때문이 아니라 Wait()와 Pulse() 메소드 때문일 것이다. Monitor.Wait() 메소드와 Monitor.Pulse() 메소드는 단순히 lock 키워드만을 사용할 때보다 더 섬세하게 멀티 스레드 간의 동기화를 가능하게 해준다. 이 두 메소드는 반드시 lock 블록 안에서 호출해야 한다. lock을 걸어 놓지 않은 상태에서 이 두 메소드를 호출한다면 CLR이 SynchronizationLockException 예외를 던지기때문이다. Wait() : 스레드를 WaitSleepJoin 상태로 만든다. Pulse..

Monitor 클래스는 스레드 동기화에 사용하는 몇 가지 정적 메소드를 제공한다. Monitor.Enter()와 Monitor.Exit() 메소드다. 이 두 메소드는 lock 키워드와 완전히 똑같은 기능을 한다. Monitor.Enter() 메소드는 크리티컬 섹션을 만든다. Monitor.Exit() 메소드는 크리티컬 섹션을 제거한다. Monitor.Enter() 메소드는 lock 블록의 { (여는 괄호), Monitor.Exit() 메소드는 lock 블록의 } (닫는 괄호) 에 해당한다고 할 수 있다. // lock 키워드 public void Increase() { int loopCount = 1000; while (loopCount-- > 0) { lock (thisLock) { count++; }..
C# 에서 const와 readonly는 상수형 타입이다. const : 컴파일 상수 readonly : 런타임 상수 const 컴파일 타입의 상수이다. 컴파일 시 const 변수의 값을 가져온다. 내장자료형 (정수형, 실수형, Enum, String)에 대해서만 사용할 수 있다. 변수 선언과 동시에 값을 할당 해야 한다. 메모리 할당 위치는 heap memory이다. const는 선언과 동시에 static이 컴파일러에 의해 자동으로 붙게된다. (정적 필드가 됨) using System; namespace CSharpExample { class Foo { // 선언과 동시에 static이 컴파일러에 의해 자동으로 붙게되어 // 정적 필드가 된다. const int bar = 55; public int B..
애플리케이션을 구성하는 각 스레드는 여러 가지 자원을 공유하는 경우가 많다. 파일 핸들이나 네트워크 커넥션, 메모리에 선언한 변수 등이 그 예다. 그런데 공유되는 자원을 여러 스레드들이 한꺼번에 변경시키려하면 문제가 발생한다. 그래서 스레드들이 정연하게 자원을 사용할 수 있도록 질서를 잡아야 할 필요가 있다. 스레드들이 순서를 갖춰 자원을 사용하게 하는 것을 일컬어 "동기화(Synchronization)" 라고 한다. 이것을 제대로 하는 것이야말로 멀티 스레드 프로그래밍을 완벽하게 하는 길이라고 할 수 있다. 스레드 동기화에서 가장 중요한 것은 "자원을 한번에 하나의 스레드가 사용하도록 보장" 하는 것이다. .NET 프레임워크가 제공하는 대표적인 도구로는 lock 키워드와 Monitor 클래스가 있다. ..
스레드는 수명이 다해 스스로 종료되는 것이 가장 좋지만, 불가피하게 스레드를 강제로 종료시켜야 하는 경우가 있다. Abort() 메소드를 사용할 때는 도중에 강제로 중단된다 해도 프로세스 자신이나 시스템에 영향을 받지 않는 작업에 한 해 사용하는 것이 좋다. 스레드가 수행 중인 작업이 강제로 중단되는 경우 시스템에 악영향을 미칠 수 있다면 조금 더 부드러운 방법을 택해야 한다. Thread.Interrupt() 메소드는 스레드가 한참 동작 중인 상태(Running 상태)를 피해서 WaitJoinSleep 상태에 들어갔을 때 ThreadInterruptedException 예외를 던져 스레드를 중지 시킨다. Abort()와 비슷하지만 Thread.Interrupt() 메소드가 조금 더 나은 방법이라 할 수..

.NET 프레임워크는 스레드의 상태를 ThreadState 열거형에 정의해두었다. 다음 표와 같다. 상태 설명 Unstarted 스레드 객체를 생성한 후 Thread.Start() 메소드가 호출되기 전의 상태이다. Running 스레드가 시작하여 동작 중인 상태를 나타낸다. Unstarted 상태의 스레드를 Thread.Start() 메소드를 통해 이 상태로 만들 수 있다. Suspended 스레드의 일시 중단 상태를 나타낸다. 스레드를 Thread.Suspend() 메소드를 통해 이 상태로 만들 수 있으며, Suspended 상태인 스레드는 Thread.Resume() 메소드를 통해 다시 Running 상태로 만들 수 있다. WaitSleepJoin 스레드가 블록(Block)된 상태를 나타낸다. 메소드..
프로세스는 사용자가 작업 관리자 등을 이용하여 임의로 죽일 수 있다. 하지만 프로세스 안에서 동작하는 각 스레드는 그런 식으로 죽일 수 없다. 살아 있는 스레드를 죽이려면 다음 예제와 같이 그 스레드를 나타내는 Thread 객체의 Abort() 메소드를 호출해줘야 한다. static void DoSomething() { try { for(int i=0; i 0) { Console.WriteLine($"{count--} left"); Thread.Sleep(10); } Console.WriteLine("Count: 0"); } catch (ThreadAbortException err) { Console.WriteLine(err); Thread.ResetAbort(); } finally { Console.W..
프로세스란? 프로세스는 실행 파일이 실행되어 메모리에 적재된 인스턴스이다. 가령 work.exe가 실행 파일이라면, 이 실행 파일을 실행한 것이 프로세스이다. 또한 프로세스는 반드시 하나 이상의 스레드(Thread)로 구성된다. 스레드란? 스레드는 운영체제가 CPU 시간을 할당하는 기본 단위인데, 프로세스가 밧줄이라면 스레드는 밧줄을 이루는 실이라고 할 수 있다. 멀티 스레드의 장점 1. 사용자 대화형 프로그램에서 멀티 스레드를 이용하면 응답성을 높일 수 있다는 점을 꼽을 수 있다. 예를 들어 제작한 프로그램이 파일을 복사하는데, 복사할 파일이 너무 커서 소요 시간이 30분 정도 걸린다고 해보자. 이 때 프로그램을 단일 스레드로 만든다면 프로그램이 파일을 복사하는 동안 사용자가 취소 명령을 내리고 싶어도..
BinaryWriter/Reader 와 StreamWriter/Reader는 기본 데이터 형식을 스트림에 쓰고 읽을 수 있도록 메소드를 제공한다. 하지만 프로그래머가 직접 정의한 클래스나 구조체 같은 복합 데이터 형식은 지원하지 않는다. BinaryWriter/Reader 와 StreamWriter/Reader로 복합 데이터 형식을 기록하고 읽으려면 그 형식이 갖고 있는 필드의 값을 저장할 순서를 정한 후, 이 순서대로 저장하고 읽는 코드를 작성해야 한다. 이 문제를 위해 C#은 복합 데이터 형식을 쉽게 스트림에 읽기/쓰기를 할 수 있는 하는 "직렬화(Serialization)" 라는 메커니즘을 제공한다. 직렬화란? 객체의 상태(객체의 필드에 저장된 값들을 의미)를 메모리나 영구 저장 장치에 저장이 가능..
텍스트 파일은 구조는 간단하지만 활용도가 높은 파일 형식이다. ASCII 인코딩에서는 각 바이트가 문자 하나를 나타내기 때문에 바이트 오더의 문제에서도 벗어날 수 있고, 이로 인해 플랫폼에 관계없이 생성하고 읽을 수 있다. 뿐만 아니라 프로그램이 생성한 파일의 내용을 편집기로 열면 사람이 바로 읽을 수도 있다. .NET 프레임워크는 텍스트 파일을 쓰고 읽을 수 있도록 StreamWriter/StreamReader를 제공한다. 이 두 클래스들은 Stream의 도우미 클래스이다. Stream이 NetworkStream이라면 네트워크를 통해 텍스트 데이터를 내보내거나 읽어들이고, FileStream이라면 파일로 텍스트 데이터를 내보내거나 이로부터 읽어들인다. StreamWriter StreamWriter sw..

FileStream 클래스는 파일 처리를 위한 모든 것을 갖고 있지만, 사용하기에 여간 불편한 것이 아니다. 특히 데이터를 저장할 때 반드시 byte 형식 또는 byte의 배열 형식으로 변환해야 한다는 문제가 있다. 이것은 파일로부터 데이터를 읽을 때도 마찬가지다. .NET 프레임워크는 FileStream의 이런 불편함을 해소하기 위해 도우미 클래스들은 제공하고 있다. 바로 BinaryWriter와 BinaryReader 클래스가 그 예이다. BinaryWriter : 스트림에 이진 데이터(Binary Data)를 기록하기 위한 목적으로 만들어진 클래스 BinaryReader : 스트림으로부터 이진 데이터를 읽어들이기 위한 목적으로 만들어진 클래스 이 두 클래스는 어디까지나 파일 처리의 도우미 역할을 할..

스트림은 영어로 시내, 강 또는 도로의 차선을 뜻하는 단어로, 파일을 다룰 때 말하는 스트림은 "데이터가 흐르는 통로"를 뜻한다. 메모리에서 하드디스크로 데이터를 옮길때에는 먼저 이 스트림을 만들어 둘 사이를 연결한 뒤에 메모리에 있는 데이터를 바이트 단위로 하드디스크로 옮겨 넣는다. 하드디스크에서 메모리로 데이터를 옮길 때도 마찬가지다. 하드디스크와 메모리 사이에 스트림을 놓은 후 파일에 담겨 있는 데이터를 바이트 단위로 메모리로 차례차례 옮겨온다. 스트림은 데이터의 "흐름"이기 때문에 스트림을 이용하여 파일을 다룰 때는 처음부터 끝까지 순서대로 읽고 쓰는 것이 보통이다 (이것을 순차 접근(Sequential Access 방식이라고 함). 이러한 스트림의 구조는 네트워크나 데이터 백업 장치의 데이터 입..
파일(File)은 컴퓨터 저장 매체에 기록되는 데이터의 묶음이다. 디렉토리(Directory)는 파일이 위치하는 주소로, 파일(서류)를 담는다는 의미에서 폴더(Folder)라고 부르기도 한다. .NET 프레임워크에서는 파일과 데릭테뢰 정보를 손쉽게 다룰 수 있도록 System.IO 네임스페이스 아래에 다음과 같은 클래스들을 제공한다. 클래스 설명 File 파일의 생성, 복사, 삭제, 이동, 조회를 처리하는 정적 메소드를 제공한다. FileInfo File 클래스와 하는 일은 동일하지만 정적 메소드 대신 인스턴스 메소드를 제공한다. Directory 디렉토리의 생성, 삭제, 이동, 조회를 처리하는 정적 메소드를 제공한다. DirectoryInfo Directory 클래스와 하는 일은 동일하지만 정적 메소드..

파이썬(Python)과 루비(Ruby)는 최근 유행하고 있는 동적 언어(Dynamic Language 또는 Dynamic Typed Language)이다. CLR(Common Language Runtime) 은 IL(Intermediate Language)로 컴파일할 수 있는 언어들은 지원하지만, 파이썬이나 루비처럼 실행할 때 코드를 해석해서 실행하는 방식의 동적 언어는 지원할 수 없다. 그래서 마이크로소프트는 동적 언어를 실행할 수 있도록 해주는 플랫폼인 DLR(Dynamic Language Runtime)을 선보였다. DLR은 CRL위에서 동적하며, 파이썬이나 루비와 같은 동적 언어를 실행할 수 있다. DLR의 장점은 그저 동적 언어를 .NET 플랫폼에서 실행할 수 있다는 정도에서 그치지 않는다. D..