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가지
- 지시문
- 상단에 using을 사용하여 import 외부 dll 파일을 사용할 수 있다.
- 문장
- 개체 범위를 정의 할 때 사용한다. 그 범위를 벗어나면 자동으로 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’ 네임스페이스에 속한 스레드 안전한 큐이다.
- 여러 스레드가 동시에 안전하게 요소를 추가하고 제거할 수 있도록 설계되었다. 이는 멀티스레딩 환경에서 데이터 구조를 안전하게 사용할 수 있게 해준다.
주요 특징
- 스레드 안정성(Thread-Safety)
- 스레드 안전하게 설계되어 여러 스레드가 동시에 큐에 접근하여 요소를 추가하거나 제거할 수 있다.
- FIFO(First-In-First-Out)
- 선입선출 방식으로 작동한다.
- 비차단(Non-Blocking)
- 대부분의 작업에서 잠금(lock)을 사용하지 않으며, 따라서 성능이 매우 좋다.
주요 메서드
- Enqueue(T item)
- 큐의 끝에 요소를 추가한다.
- TryDequeue(out T result)
- 큐의 시작 부분에서 요소를 제거하고, 제거된 요소를 result에 할당한다.
- 성공하면 true, 큐가 비어 있으면 false를 반환한다.
- TryPeek(out T result)
- 큐의 시작 부분에서 요소를 제거하지 않고, 해당 요소를 result에 할당한다.
- 성공하면 true, 큐가 비어 있으면 false를 반환한다.
- IsEmpty
- 큐가 비어 있는지 여부를 확인한다.
- Count
- 큐에 있는 요소의 개수를 반환한다. 다만, 이 속성은 즉시 일관성을 보장하지 않는다.
- 다른 스레드가 요소를 추가하거나 제거하는 동안 값이 변경될 수 있다.
Invoke & BeginInvoke
Invoke
- Control.Invoke
- 컨트롤의 내부 핸들이 있는 스레드에서 지정된 대리자를 실행하는 방법이다.
- UI 컨트롤 스레드에서 실행되지만 호출 스레드가 실행되기 앞서 기존 스레드 완료를 기다리고 호출된다.
- Delegate.Invoke
- 동일한 스레드에서 사용할 대리자를 동기적으로 실행하는 방법이다.
- 컨트롤의 본인 스레드가 아닌 다른 스레드를 이용하여 해당 컨트롤 객체를 동기식으로 실행하는 방법이다.
BeginInvoke
- Control.BeginInvoke
- 컨트롤의 기본 핸들이 만들어진 스레드에서 대리자를 비동기적으로 실행하는 방법이다.
- 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)의 경우 여러 스레드가 동일한 자원에 동시에 접근하려고 할 때 발생하는 문제로 다음과 같은 이유로 성능 저하를 일으킬 수 있다.
- 경합의 본질
- 여러 스레드가 동시에 동일한 변수에 접근하고자 할 때, 그 변수에 대한 접근 권한을 얻기 위해 기다려야 할 수 있다.
- CPU 캐시 라인
- Interlocked 연산은 메모리에서 값을 읽고 수정한 다음 다시 쓰는 작업을 수행한다. 이 과정에서 CPU 캐시 라인이 여러 스레드 간에 공유되며, 이로 인해 캐시 동기화 비용이 발생할 수 있다. 여러 스레드가 동일한 메모리 주소에 접근하면 캐시 일관성을 유지하기 위한 프로토콜에 따라 캐시 라인이 무효화되고, 성능이 저하된다.
- 스핀락
- 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
경과 시간을 정확하게 측정하는 데 사용할 수 있는 일련의 메서드와 속성을 제공한다.
'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 |