Study/TIL(Today I Learned)

24.07.25 C#

에린_1 2024. 7. 25. 20:16
728x90

C#

Out 매개변수 한정자

  • out 키워드를 사용하면 변수가 참조로 전달이 된다.
  • out 키워드를 사용한 매개변수는 함수 내부에서 무조건 값을 세팅해주어야 한다.
    • 프로퍼티(=속성)는 변수가 아니므로 out 매개변수로 전달할 수 없다.

참조

https://blockdmask.tistory.com/606

 

[C#] out 매개변수 한정자 설명 및 예제 (out 키워드)

안녕하세요. BlockDMask입니다. 지난 시간에 ref 키워드 포스팅에서 call by value, call by reference에 대해서 배우고 in 키워드에 대해서도 배워봤습니다. 오늘은 C#에서 매개변수를 넘길 때 붙여줄 수 있는

blockdmask.tistory.com

 

Using

  • C# Using문 사용법 2가지
    1. 지시문
      • 상단에 using을 사용하여 import 외부 dll 파일을 사용할 수 있다.
    2. 문장
      • 개체 범위를 정의 할 때 사용한다. 그 범위를 벗어나면 자동으로 dispose(처분)된다. file, font, DB의 같은 경우에 사용할 때 일정부분의 메모리를 잡아 먹는데 이 부분에서 컴퓨터의 자원이 할당 되는 것이다. 메소드나 어떤 형식의 로직이 끝날 때 이 부분을 다시 반납해야 성능이 개선되고 프로그램의 문제가 발생하지 않는다.
      • using문을 메소드 안에 커넥트 형식으로 {} 안에서만 사용하고 나면 바로 dispose 되게 만들어준다.

참조

https://magpienote.tistory.com/65

 

c# using 문 사용 법 사용 이유

c# using 문 사용법 사용 용도 2가지 1. 지시문 상단에 using을 사용하여 import 외부 dll파일을 사용할 수 있다. using System.Text; using project = PC.MyCompany.Project; 별칭 2. 문장 개체 범위를 정의 할때 사용한다

magpienote.tistory.com

 

Dispose

  • C#은 가비지 컬렉터(GC)가 메모리를 자동으로 관리한다. 필요 없는 클래스의 인스턴스를 메모리에서 바로 지우는 게 아니라, 조건이 될 때까지 기다렸다가 지우기 때문에 클래스를 지웠다고 해도 바로 삭제되는 것은 아니다.
  • 일반적인 메모리라면 GC에 맡겨도 상관이 없지만, 관리되지 않는(Unmanaged Native) 리소스는 즉각 해제해야 하는 경우가 생기는데, 그런 경우 Dispose를 사용한다.

참조

https://chomdoo.tistory.com/15

 

C# 에서 Dispose의 개념과 궁금했던 몇가지 사항

C#은 가비지 컬렉터(GC)가 메모리를 자동으로 관리한다. 필요 없는 클래스의 인스턴스를 메모리에서 바로 지우는 게 아니라, 조건이 될 때까지 기다렸다가 지우기 때문에 클래스를 지웠다고 해도

chomdoo.tistory.com

 

ConcurrentQueue<T>

  • .NET의 ‘System.Collections.Concurrent’ 네임스페이스에 속한 스레드 안전한 큐이다.
  • 여러 스레드가 동시에 안전하게 요소를 추가하고 제거할 수 있도록 설계되었다. 이는 멀티스레딩 환경에서 데이터 구조를 안전하게 사용할 수 있게 해준다.

주요 특징

  1. 스레드 안정성(Thread-Safety)
    • 스레드 안전하게 설계되어 여러 스레드가 동시에 큐에 접근하여 요소를 추가하거나 제거할 수 있다.
  2. FIFO(First-In-First-Out)
    • 선입선출 방식으로 작동한다.
  3. 비차단(Non-Blocking)
    • 대부분의 작업에서 잠금(lock)을 사용하지 않으며, 따라서 성능이 매우 좋다.

주요 메서드

  1. Enqueue(T item)
    • 큐의 끝에 요소를 추가한다.
  2. TryDequeue(out T result)
    • 큐의 시작 부분에서 요소를 제거하고, 제거된 요소를 result에 할당한다.
    • 성공하면 true, 큐가 비어 있으면 false를 반환한다.
  3. TryPeek(out T result)
    • 큐의 시작 부분에서 요소를 제거하지 않고, 해당 요소를 result에 할당한다.
    • 성공하면 true, 큐가 비어 있으면 false를 반환한다.
  4. IsEmpty
    • 큐가 비어 있는지 여부를 확인한다.
  5. Count
    • 큐에 있는 요소의 개수를 반환한다. 다만, 이 속성은 즉시 일관성을 보장하지 않는다.
    • 다른 스레드가 요소를 추가하거나 제거하는 동안 값이 변경될 수 있다.

Invoke & BeginInvoke

Invoke

  1. Control.Invoke
    • 컨트롤의 내부 핸들이 있는 스레드에서 지정된 대리자를 실행하는 방법이다.
    • UI 컨트롤 스레드에서 실행되지만 호출 스레드가 실행되기 앞서 기존 스레드 완료를 기다리고 호출된다.
  2. Delegate.Invoke
    • 동일한 스레드에서 사용할 대리자를 동기적으로 실행하는 방법이다.
  • 컨트롤의 본인 스레드가 아닌 다른 스레드를 이용하여 해당 컨트롤 객체를 동기식으로 실행하는 방법이다.

BeginInvoke

  1. Control.BeginInvoke
    • 컨트롤의 기본 핸들이 만들어진 스레드에서 대리자를 비동기적으로 실행하는 방법이다.
  2. Delegate.BeginInvoke
    • 컨트롤의 내부 핸들이 만들어진 스레드에서 지정된 인수를 사용하여 지정된 대리자를 비동기적으로 실행하는 방법이다.
  • 컨트롤의 본인 스레드가 아닌 다른 스레드를 이용하여 해당 컨트롤 객체를 비동기식으로 실행하는 방법이다.

ArraySegment

  • 배열(Array)의 특정 데이터를 참조할 수 있게 해주는 래퍼(Wrapper)이다.
  • 1차원 배열의 래퍼로 배열 내의 요소를 길이(범위)를 지정하여 구분한다.
  • 구분되어 있는 배열의 범위를 참조하기 때문에 사용할 때 새로운 배열을 만들지 않는다.
  • 배열의 일부만 나타내는 개체를 상대적으로 비용이 많이 드는 메서드 Copy를 호출하는 대신 메서드에 인수로 전달 ArraySegment 하여 배열의 일부 복사본을 전달할 수 있다.
  • 다중 스레드 앱에서 구조를 사용하여 각 스레드가 ArraySegment 배열의 일부에서만 작동하도록 할 수 있다.
  • ArraySegment는 불변(immutable) 구조체(struct)이기 때문에 내용을 변경할 수 없다.
    • 원본 배열을 보호하면서 배열의 일부를 참조하고자 할 때 유용하다.

Array와 ArraySegment의 차이점

  • 배열의 특정 위치에서 특정 크기만큼 참고하고 싶은 때 보통 새로 배열을 만든 후 복사해야 원하는 데이터만 참조할 수 있다.
  • ArraySegment를 사용하면 새로 배열을 만들지 않으면서 버퍼의 특정 데이터를 참조할 수 있다.

Interlocked

  • 다중(멀티) 스레드에서 공유하는 변수에 대한 원자 단위 연산을 제공하는 클래스이다.
Interlocked.Increment(ref number);
  • Increment는 원자성이 보장된 number에 +1을 하는 함수이다.
  • number의 값을 인자로 넣는게 아니라 참조 값을 넘긴다.

문제점

  • 원자성을 보장하기 위해 하드웨어 레벨에서 작동하므로 다른 일반 연산보다 더 많은 오버헤드가 발생한다.
  • 여러 스레드가 동일한 자원에 동시에 액세스 하려고 할 때 경합이 발생할 수 있다. 이런 경합 문제는 스레드들이 자원을 기다리며 시간을 낭비하게 만들고 전체 프로그램의 성능을 저하시킨다.
    • 경합과 경쟁에 대해서 착각을 했다.
    • 경합(Contention)의 경우 여러 스레드가 동일한 자원에 동시에 접근하려고 할 때 발생하는 문제로 다음과 같은 이유로 성능 저하를 일으킬 수 있다.
      1. 경합의 본질
        • 여러 스레드가 동시에 동일한 변수에 접근하고자 할 때, 그 변수에 대한 접근 권한을 얻기 위해 기다려야 할 수 있다.
      2. CPU 캐시 라인
        • Interlocked 연산은 메모리에서 값을 읽고 수정한 다음 다시 쓰는 작업을 수행한다. 이 과정에서 CPU 캐시 라인이 여러 스레드 간에 공유되며, 이로 인해 캐시 동기화 비용이 발생할 수 있다. 여러 스레드가 동일한 메모리 주소에 접근하면 캐시 일관성을 유지하기 위한 프로토콜에 따라 캐시 라인이 무효화되고, 성능이 저하된다.
      3. 스핀락
        • Interlocked 연산이 경합을 피하기 위해 스핀락(짧은 시간 동안 반복적으로 재시도)을 사용 하는 경우, CPU 리소스를 낭비할 수 있다. 특히, 경합이 매우 빈번하게 발생하면 많은 CPU 사이클이 낭비된다.

as/ is/ this/ base

as

  • 명시적 형변환에 사용되는 키워드이다.
  • 형변환이 가능하면 변환된 인스턴스를 반환하고 그렇지 않으면 null을 반환한다.
  • 참조 형식에만 사용 가능하다.
  • 형변환이 실패했을 때, ()을 사용한 명시적 형변환의 경우 런타임 에러가 발생하지만 as 연산자를 사용할 경우 에러가 발생하지 않고 null을 반환한다.

is

  • 형변환의 가능성 여부를 bool값으로 반환한다.
  • 값 형식, 참조 형식 모두 사용 가능하다.
  • C# 7.0부터 is 연산자를 as 연산자처럼 사용할 수 있게 됐다.

this

  • 클래스 내부에서 인스턴스 자신을 가리키는 키워드이다.

base

  • 부모 클래스 인스턴스를 가리키는 키워드이다.
  • this와 가리키는 대상이 다를 뿐 사용 패턴은 유사하다.

SocketAsyncEventArgs

  • .NET의 비동기 소켓 프로그래밍에서 사용되는 클래스이다. 이 클래스는 네트워크 소켓 작업을 효율적으로 처리하기 위해 설계되었으며, 특히 높은 성능과 확장성을 요구하는 서버 응용 프로그램에서 유용하다.
  • Socket 통신을 하기 때문에 Socket이고, 비동기로 작업ㅇ르 하기 때문에 Async이다. 작업을 완료하면 실행되는 완료 콜백 함수를 가질 수 있어 Event이고, Socket 클래스의 비동기 함수에 인수로 들어가기 때문에 Args라고 생각하면 된다.
  • Socket 클래스의 함수 중 뒤에 Async가 붙는 함수들은 모두 아래의 형태로 되어 있다.
public bool *** Async(SocketAsyncEventArgs e); 
  • SocketAsyncEventArgs를 활용한 비동기 통신을 할 때의 대략적인 순서는 SocketAsyncEventArgs 객체를 만들어 필요한 설정을 하고, Socket 함수에 인수로 넣어 호출하는 방식으로 진행되야 한다.
  • ‘System.Net.Sockets’ 네임스페이스에 포함되어 있다.

멤버

  • Completed
    • 이벤트 핸들러. 작업이 완료되면 이 곳에 추가된 함수가 실행된다.
  • SetBuffer(byte[], int, int)
    • 함수. 객체에 담을 데이터의 크기를 설정한다.
  • RemoteEndPoint
    • 프로퍼티. IP와 포트번호를 갖는 EndPoint 클래스를 갖는다.
  • AcceptSocket
    • 프로퍼티. 현재 작업과 연결된 소켓을 갖는다. Socket 리턴
  • UserToken
    • 프로퍼티. 현재 작업과 연결된 사용자(소켓) 또는 애플리케이션 개체를 갖는다. object 리턴.
  • SocketError
    • 프로퍼티. 소켓의 각종 에러 상태를 갖는데, Success도 있어 에러가 없을을 알 수 있다.
  • Buffer
    • 프로퍼티. byte[] 송수신될 데이터를 갖는다.
  • BytesTransferred
    • 프로퍼티. 소켓에서 전송된 바이트 수를 리턴한다.
  • offset
    • 프로퍼티. Buffer가 참조할 데이터의 오프셋이다.

참조

https://siku314.tistory.com/75

 

[네트워크/C#] SocketAsyncEventArgs를 이용한 비동기 TCP 통신

# SocketAsyncEventArgs 클래스 SocketAsyncEventArgs 클래스는 비동기 소켓 통신을 할 때 송신과 수신 자체 작업을 담당하는 클래스입니다. Socket 통신을 하기 때문에 Socket이고, 비동기로 작업을 하기 때문에

siku314.tistory.com

 

ConstainsKey

  • Dictionary에 키를 추가하는 경우 키가 포함되어 있는지 확인을 할 때 사용한다.

ConcurrentDictionary<TKey,TValue>.AddOrUpdate 메서드

  • 키가 아직 없는 경우 ConcurrentDictionary<TKey, TValue>에 키/값 쌍을 추가하고, 키가 이미 있는 경우 키/값 쌍을 업데이트 한다.

Stopwatch

경과 시간을 정확하게 측정하는 데 사용할 수 있는 일련의 메서드와 속성을 제공한다.

728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.07.29 C#, 게임 서버  (0) 2024.07.29
24.07.26 C#  (0) 2024.07.26
24.07.24 C#  (1) 2024.07.24
24.07.23 RedMine  (0) 2024.07.23
24.07.22 SVN  (0) 2024.07.22