c#

  • [c#] 헷갈리는 nested class의 인스턴스

    위 코드에서 ChildClass의 인스턴스는 두 개 생긴다. parentClass.ChildClass는 ParentClass parentClass = new()로 parentClass가 만들어질 때 parentClass의 컨스트럭터가 생성하고 childClass는 ChildClass childClass = new(parentClass)로 만들어진다. parentClass.ChildClass와 childClass는 부모 클래스는 parentClass로 같다. 하나의 부모 클래스 아래에 두 개의 서로 다른 자식 클래스들이 있는 거다.

  • [c#] 멀티 뜨레드에서 lock과 await 같이 쓰기

    아래의 코드에서 TestMethod1는 멀티 뜨레드에서 작동한다. 이 메떠드는 다른 뜨레드에서 실행되는 메떠드와 동기화되어야 한다. 그러면서 await도 해야 한다. await를 lock 블록 안에서 쓰면 오류로 처리된다. 만약 await가 긴 시간을 쓴다면 lock이 걸린 다른 뜨레드는 그 시간을 기다려야 하기 때문이다. 이러면 멀티 뜨레드를 쓰는 의미가 줄어든다. 아래의 코드처럼 lock 블록 안에서 네스티드 메떠드를 만들어 await를 쓰면…

  • [c#] 시간 계산하기 – TimeOnly

    DateTime은 날짜와 시간을 모두 값으로 갖고 DateOnly는 날짜만 TimeOnly는 시간만 갖는다. 하루 안에서 시간들을 연산하려면 TimeOnly를 쓰는 게 편하다. TimeOnly를 이용할 때 주의해야 할 게 있다. 아래 코드는 -00:00:01을 반환하지 않는다. Because TimeOnly only represents a 24-hour period, it rolls over forwards or backwards appropriately when adding values supplied to those three methods.How to use the DateOnly…

  • [c#] 클래스 리스트를 쉽게 DataGridView에 바인드하기 – ObservableObject

    클래스 리스트를 DataGridView에 연결하여 리스트 아이템의 필드가 바뀐 때 후자에 반영되게 하려면 INotifyPropertyChanged.PropertyChanged 이벤트를 써야 한다. 이거는 원칙적으로 클래스의 각 필드에 구현을 해야 한다. 많이 번거롭고 코드도 길어진다. 더 편하게 하려면 클래스 리스트를 쓰지 않고 아예 DataTable을 이용한다. 하지만 이건 클래스 리스트보다 느리다. 변칙적인 방법인데 ObservableObject를 이용하면 클래스 리스트를 이용해서도 쉽게 구현할 수 있다. 이걸…

  • [c#] task와 lambda expression을 이용한 멀티 뜨레드

    전에는 멀티 뜨레드를 이용할 때 thread나 ThreadPool을 이용했지만 요샌 task를 쓴다. task로 새 뜨레드를 만들 땐 run이나 StartNew를 이용한다. 전자가 더 편하고 빠르다. run을 이용하면 새로운 뜨레드로 실행할 메떠드를 그대로 쓸 수 있다. 하지만 람다식을 써야 한다. StartNew로 하려면 대상 메떠드가 패러미터로 object만 받을 수 있다. 이걸 다시 타입캐스트해서 써야 하므로 번거롭다. 지나치게 간결한 건…

  • [c#] Contol.Invoke와 Control.BeginInvoke의 비교

    Invoke와 BeginInvoke는 멀티 뜨레드를 다룰 때 자주 쓴다. Invoke는 Control로 제어권이 넘어간 뒤 돌아올 때를 기다리고 BeginInvoke는 기다리지 않는다. 조금 더 어렵게 설명하면 전자는 synchronous 즉 동기적이고 후자는 asynchronous 즉 비동기적이다. 아래 예제에서 BeginInvoke를 한 거는 label 출력 명령을 떠나 보낸 뒤 바로 제 갈 길을 간다. 따라서 BeginInvoke가 실행된 뒤 그 끝을 기다리지 않고…

  • [c#] 경로가 맞는데도 LoadLibrary가 126을 반환하고 실행되지 않는 문제

    아래의 코드는 0을 반환해야 하지만 126을 반환하는 경우도 있다. LoadLibrary가 파일을 찾지 못하면 GetLastWin32Error는 126을 반환한다. 그러나 File.Exists(path)로 확인을 한 상태이므로 126을 반환해서는 안 된다. 이 문제에 대해 검색을 해 보면 dependency가 어쩌구 하며 여러 설명들이 나오지만 내가 보기엔 그저 버그다. 같은 코드가 어떤 컴퓨터에서는 0을 반환하고 다른 거에서는 126을 반환하기도 하며 후자의 경우에도 정적으로…

  • LoadLibrary 오류 처리 방법

    LoadLibrary에 대한 자세한 설명은 따로 했다. LoadLibrary는 제대로 작동하지 않으면 그 이유를 정수 형태의 에러 메시지로 반환한다. 그러나 이러한 반환을 위해서는 아래와 같이 DllImportAttribute.SetLastError를 true로 설정해야 한다. 로드가 되지 않으면 Marshal.GetLastWin32Error 메떠드를 이용하여 아래와 같이 원인을 확인한다. GetLastWin32Error는 LoadLibrary를 실행한 바로 뒤에 실행해야 하는 거에 유의한다. 아래의 코드는 제대로 작동하지 않아 0을 반환한다. 그 이유는…

  • 프로그램 코드로 웹패이지가 열리지 않는 경우 – user agent header

    웹 브라우저로는 잘 열리는 url이 아래와 같은 코드로는 열리지 않는 경우가 있다. 서버가 http의 user agent header를 요구하기 때문이다. HTTP headers let the client and the server pass additional information with a message in a request or response.– HTTP headers, mdn web docs agent는 어려운 단어다. 흔히 대리인이라 번역하지만 computer와 관련되어서는 그렇지 않다. (computing) In…