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

 

그래서, C++의 경우 소멸자에 각종 변수의 메모리를 해제하는 것으로 간단하게 구현이 될 만한 내용이지만, C#에서는 바로 삭제가 필요한 리소스를 해제하기 위해서 Dispose 함수가 필요하다.

 

소멸자와 Dispose의 차이 : stackoverflow.com/questions/339063/what-is-the-difference-between-using-idisposable-vs-a-destructor-in-c?newreg=eff4d2b40e844d5581272cc65983c418

 

What is the difference between using IDisposable vs a destructor in C#?

When would I implement IDispose on a class as opposed to a destructor? I read this article, but I'm still missing the point. My assumption is that if I implement IDispose on an object, I can

stackoverflow.com

그런데, Dispose를 호출하는 걸 깜박하면 어떻게 될까?

그럴 경우에는 GC에서 해당 인스턴스를 제거할 때, (소멸자에서) Dispose를 호출해준다.

큰 문제가 없으면 그냥 냅 둬도 상관없다는 얘기인데, 다만 다음과 같은 부작용이 생길 수 있다고 한다.

 

1.GC가 해당 인스턴스를 언제 지울 지 알 수 없다.

 즉, Dispose가 언제 호출될지 알 수 없다. 애플리케이션이 종료될 때까지 호출이 안될 수도 있다. 중요한 리소스를 사용하거나, 메모리를 많이 먹는 클래스라면 위험할 수도 있겠다.

 

2.GC가 해당 인스터스를 지울 때 Dispose를 호출하게 되면 그 순간 부하가 걸린다.

 즉, 랜덤하게 랙을 유발할 수도 있다. 성능에 예민한 앱이라면 주의가 필요하다.

 

3.GC가 해당 인스턴스를 지울 때 Dispose에서 예외가 발생하면 어플 자체가 크래시 할 수도 있다.

 수동으로 Dispose를 할 때에는 try/catch로 보호할 수 있지만, 자동제거일 경우 예외를 잡을 수 없기 때문에 매우 위험할 수도 있다.

 

참고 링크 : stackoverflow.com/questions/32397248/what-happens-if-i-dont-call-dispose

 

 

매번 Dispose를 호출하기 귀찮을 때는 using 블록을 사용하면 된다. using을 사용하면 자동으로 Dispose를 해준다.

using과 try/catch를 같이 사용해야 할 때에는 using을 try 안쪽에 넣으면 된다.

 

참고 링크 : theeye.pe.kr/archives/2736

 

Unity C# – IDisposable 알아보기 | 아이군의 블로그

이번에는 IDisposable 인터페이스에 대해서 알아보겠습니다. C#은 가비지콜랙터(Garbage Collector)를 가지고 있습니다. 이 GC는 기본적으로 관리되는 모든 객체들의 참조 링크를 관리하며 더이상 참조되

theeye.pe.kr

 

Dispose 기능이 필요한 커스텀 클래스를 만들어야 할 때에는 IDisposal을 상속 받아서 만들면 된다.

 

참고 링크  : medium.com/dotnetdev/idisposable-%ED%8C%A8%ED%84%B4%EC%9D%98-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B5%AC%ED%98%84-%EB%B0%A9%EB%B2%95-4fa0fcf0e67a

 

IDisposable 패턴의 올바른 구현 방법

.NET Framework에서 새로운 클래스를 만들 때 여러가지 메모리 관리 디자인 패턴과 기법을 적용할 수 있지만, 한시적으로 사용해야 할 필요가 있는 자원들을 묶어서 관리할 때에는 IDisposable 패턴을

medium.com

참고 링크 2 : codeless.tistory.com/entry/C-Disposable-%ED%8C%A8%ED%84%B4

 

C# Disposable 패턴

public class MyResourceHog : IDisposable { private bool alreadyDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing)..

codeless.tistory.com

 

먼저 새로운 깃 서버에서 빈 저장소를 하나 생성한다.

(이때 아무것도 없는 깨끗한 상태의 빈 저장소이어야 한다.)

 

본인 PC 로컬에 새로운 폴더를 하나 만든다.

콘솔창을 열고 해당 폴더로 이동한다.

 

해당 폴더에서 기존 서버 저장소의 내용을 내려 받는다.

 

git clone --mirror <기존 저장소 주소> .\

 

기존 서버와 연결을 끊는다.

 

git remote rm origin

 

새로운 저장소 주소로 연결한다.

 

git remote add origin <새 저장소 주소>

 

새 저장소로 전부 업로드한다.

git push --mirror

 

다른 폴더에서 클론을 받아서 로그, 태그, 브랜치 등을 확인한다.

WPF 윈도우 타입을 None으로 하면 테두리와 타이틀바도 사라져서 깔끔해지지만, 최소화 및 닫기 등 시스템 버튼도 사라져서 불편해진다. 그래서, None 스타일을 유지하면서도 이런 시스템 버튼을 다시 추가하고 싶은 경우가 있다.

 

닫기 버튼은 x 글자를 넣고, 최소화 버튼은 언더바( _ ) 글자로 대신 넣어도 되지만, 최대화 및 복구버튼은 딱히 방법이 없다. 그래서 찾아보니, 예전부터 윈도우에는 이런 특수한 기호를 표현하기 위한 폰트가 이미 존재하고 있었다.

 

해당 폰트의 이름은 "Webdings"이다. 이미 윈도우 98부터 사용되고 있었다고 하니 호환성 걱정은 필요 없다.

자세한 내용은 위키 참고 => en.wikipedia.org/wiki/Webdings

 

Webdings - Wikipedia

Webdings is a TrueType dingbat typeface developed in 1997. It was initially distributed with Internet Explorer 4.0, then as part of Core fonts for the Web, and is included in all versions of Microsoft Windows since Windows 98. All of the Webding glyphs tha

en.wikipedia.org

 

위와 같이 기호만 들어 있는 폰트인데, 시스템 버튼에 필요한 내용은 빨간 박스 안에 있는 4개이다.

각각, 다음과 같다.

 

0 : 최소화

1 : 최대화

2 : 복귀

r : 닫기

 

xaml 코드는 대략 다음과 같다.

            <Button FontFamily="Webdings"
                    x:Name="ChangeViewButton"
                    Content="2"/>
            <Button FontFamily="Webdings"
                    x:Name="MinimizeButton"
                    Content="0"/>
            <Button FontFamily="Webdings"
                    x:Name="MaximizeButton"
                    Content="1"/>
            <Button FontFamily="Webdings"
                    x:Name="CloseButton"
                    Content="r"/>

하지만 이렇게만 만들어서 넣으면 이쁘지 않다.

Webdings 폰트를 이용해서 시스템 버튼을 다시 추가한 이미지

 

테두리와 배경색을 없애는 스타일을 만들어서 사용하면 더 이쁘게 나온다.

    <Style x:Key="SystemButton" TargetType="{x:Type Button}">
        <Setter Property="FontFamily" Value="Webdings"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Foreground" Value="Gray"/>
        <Setter Property="MinWidth" Value="40"/>
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Background" Value="{x:Null}"/>
        <Setter Property="BorderBrush" Value="{x:Null}"/>
    </Style>

위와 같은 스타일을 만들고,

            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="ChangeViewButton"
                    Content="2"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="MinimizeButton"
                    Content="0"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="MaximizeButton"
                    Content="1"/>
            <Button Style="{DynamicResource SystemButton}" 
                    x:Name="CloseButton"
                    Content="r"/>

버튼에서 해당 스타일을 가져다 쓰자.

 

그러면 이렇게 이쁘게 나온다.

'개발 > WPF' 카테고리의 다른 글

[WPF] BackgroundWork 사용 예제  (0) 2021.03.27
[WPF] 기본 버튼의 스타일을 바꾸는 방법  (0) 2020.12.26
[WPF] 테마와 스킨  (0) 2020.12.24

+ Recent posts