블로그 이미지
.NETer

calendar

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

Notice

2009. 1. 6. 15:44 Reflection .NET/C#

프로젝트를 진행하다 보면 도메인간에 데이터를 주고 받는 경우가 많이 발생을 한다. 도메인간에 데이터를 주고 받을 때 .NET에서는 Serializable Attribute를 사용하여 객체를 직렬화해야만 한다. 그런데 간혹 데이터 사이즈가 너무 큰 경우 압축을 하고 싶은 경우가 있다. 이 경우 압축을 해서 데이터를 주고 받으면 약간의 효율이 좋을 수 있다. 이 부분은 닭이 먼저인지 달걀이 먼저 이겠지만 요즘같이 네트워크가 좋아진 상태에서 굳이 데이터를 압축하고 전송한 후 압축을 풀고 하는 과정을 시스템에 맡기는 것은 압축 하고 해제 하는 부분에서 또한 성능을 저해 할 수 있는 요소가 발생한다. 라고 하는 사람이 있을 것이고, 또 한 부류는 꺼꾸로 요즘 시스템의 가격이 저렴해지고, 시스템 성능은 많이 향상 되어 있는 상태에서 네트워크 트래픽을 줄이는 것이 더 효율적이라고 말하는 사람이 있을 것이다.

뭐가 됐던 간에 오늘은 도메인간의 데이터를 주고 받기 위해 객체를 압축하고 압축된 객체를 해제 하는 방법에 대해 알아 보도록 하겠다. 첫 번째의 경우야 그냥 데이터를 주고 받으면 그만 이기 때문에 보여줄 것이 없다.

.NET Framework 2.0 새로 추가된 GZipStream 클래스를 이용해 압축/해제를 할 수 있다. 이 클래스는 압축공개 알고리즘인 GZip file format specification 4.3 (http://www.ietf.org/rfc.html 에서 검색 할 수 있다.)을 이용해 만들어져 있다. 문제는 이 클래스만 이용해서는 Object를 압축 할 수 있지만 압축 되는 것처럼 객체의 사이즈가 줄어 든 것을 확인 할 수 있다. 이 것을 도메인간에 데이터를 넘긴 후 압축 해제를 시도 하면 압축 해제 할 때 헤더의 정보가 잘못 됐다는 둥 하면서 에러를 발생 시킨다. 그래서 MSDN 이곳 저곳을 찾아 봤지만 해결방법은 나와 있지 않다. 그래서 이리 저리 돌아 다니면서 확인한 결과 GZipStream을 가지고 압축을 한 후 헤더 정보를 만들어서 추가를 해야지만 해제를 할 때 그 헤더 정보를 이용해 압축을 해제 할 수 있다. 그 헤더의 정보는 압축 되기 전의 객체의 사이즈를 추가 하는 것이다. 이 것을 알아야 해제 할 때도 Steam 객체를 이용해 어디 까지 읽을 것인지를 결정할 수 있는 것이다. 아래 소스는 객체를 압축 하고 해제 하는 메소드를 구현한 내용이다.

참고로 GZipSteam 클래스를 이용해 압축 한 후 파일로 쓰는 것은 특별의 헤더 정보를 추가 하지 않아도 된다. 해제 할 때 도 마찬가지 이다. 이 경우는 메모리의 데이터를 압축해서 그 데이터를 전송한 후 해제 할 때만 해당 되는 내용이다.

 

  1. 압축 하기 메소드

 

2. 압축 해제 하기 메소드

 

2009년 1월 6일 조금 있다가 외근을 준비 하면서 오늘 춥네요 ^^ .NETer

posted by .NETer
2008. 9. 30. 18:07 Reflection .NET/C#

Singleton 패턴은 아주 Simple 한 패턴 중에 하나로 .NET 애플리케이션에서 흔히 사용된다. Singleton은 하나의 애플리케이션 또는 하나의 App 도메인에서 인스턴스가 하나만 존재하는 것을 말한다. 한번 생성된 인스턴스는 애플리케이션이 종료 되기 전까지 그 값을 유지 하게 되는 경우다. 그럼 이 패턴을 어떤 곳에 적용할 수 있는지 고민을 해보자. 애플리케이션에서 프린터를 제어하는 클래스가 있다고 가정을 했을 경우 어떤 화면에서 호출을 하던 인스턴스가 하나만 존재하여 요청된 작업을 큐에 쌓는다던지 아니면 현재 프린터가 일을 하고 있는지 등을 체크 할 수 있을 것이다. 이런 패턴을 사용하지 않는다고 가정을 하면 매번 new 연산자를 사용하여 클래스의 인스턴스를 생성하게 되거나 혹은 인스턴스가 소멸하게 되면 현재 작업 중인 것을 잃게 될 것이다. 결국 Singleton 패턴은 클래스의 현재 상태를 유지 할 수 있는 것으로 볼 수 있다.

C#으로 구현을 하면 두 가지 형태로 구현이 가능할 것이다.

 

  1. 일반적인 Singleton (Not Thread Safety)

 

using System;

 public sealed class SimpleSingleton

{

/// <summary>

/// 멤버 Instance

/// </summary>

private static SimpleSingleton _instance = null;

 

/// <summary>

/// 생성자

/// </summary>

private SimpleSingleton()

{

}

 

/// <summary>

/// Class Instance

/// </summary>

public static SimpleSingleton Instance

{

get

{

if (_instance == null)

{

_instance = new SimpleSingleton();

}

return _instance;

}

}

 

/// <summary>

/// 일반 메서드

/// </summary>

/// <param name="code"></param>

/// <returns></returns>

public bool IsValidate(string code)

{

return true;

}

}

 

 

위의 코드의 경우가 가장 일반적인 Singleton 패턴을 구현한 것이다. 실제 코딩을 할 때는 아래와 같이 사용할 수 있다.

 

bool result = SimpleSingleton.Instance.IsValidate();

 

이 패턴의 경우 Thread 상황에서 안전하지 않게 수행 되기 때문에 아래의 코드가 좀더 좋은 코드가 될 것이다.

 

 

  1. Thread Safety Singleton

 

using System;

 

public sealed class SimpleSingleton

{

/// <summary>

/// 멤버 Instance

/// </summary>

private static readonly SimpleSingleton _instance = null;

 

/// <summary>

/// Multithread 처리를 위한 object 생성

/// </summary>

private static object _syncRoot = new object();

 

/// <summary>

/// 생성자

/// </summary>

private SimpleSingleton()

{

}

 

/// <summary>

/// Class Instance

/// </summary>

public static SimpleSingleton Instance

{

get

{

lock (_syncRoot)

{

if (_instance == null)

{

_instance = new SimpleSingleton();

}

return _instance;

}

}

}

 

/// <summary>

/// 일반 메서드

/// </summary>

/// <param name="code"></param>

/// <returns></returns>

public bool IsValidate(string code)

{

return true;

}

}

위의 경우는 해당 클래스가 Multithread 상황에서도 안전하게 인스턴스를 보호 할 수 있게 된다. 소스를 보면 알겠지만 인스턴스를 보호하기 위해 C#의 키워드인 lock 문장을 사용하고 있다.

 

2008년 9월 말일 가을 날씨 속에 .NETer

posted by .NETer
prev 1 next