csharp

C#

C#은 MS에서 만든 프로그래밍 언어이다.

거의 완벽한 언어가 아닐까? 유일한 단점은 닷넷 프레임워크(.NET Framework)가 윈도우 계열 운영체제에만 있다는 것이라고 생각한다. 라고 생각하면서 위키의 C_샤프 문서를 보았더니 다른 플랫폼에서도 사용 가능한 GTK C#, 모노_(소프트웨어)가 있다고 한다.

장난감 만들기에 딱 좋을 정도로 쉽지만, 큰 프로그램을 만드는 데 전혀 지장 없을 정도로 강력하다.

개인적인 의견으로는 Java보다 뛰어난 언어라고 생각한다. 플랫폼이 발목을 잡아서 그렇지…

하아… 참 언어 빠르게 발전한다고 느낀다. 언어 자체의 특징보다 글쓴이가 신기하다고 느낀점을 기록한다.

루비, 자바, C#을 비교한 문서를 찾다가 희안한 코드를 보았다.1) 파일을 읽어 화면에 출력하면서 옆에 라인 번호를 함께 표시하는 프로그램이랜다. 별게 다 되는구나… 뭔가 루비스럽다.

  int number = 1;
  Array.ForEach(File.ReadAllLines(args[0]),
    line => Console.WriteLine("{0}: {1}", number++, line));

이제 효율적으로 자원을 활용하기 위한 비동기를 언어 차원에서도 지원한다. 이런 상황을 가정해 보자.

CPU를 최대한 활용하여 가지고 있는 자료를 가공하고, 인터넷에 있는 정보를 가져와 결합하는 메서드가 있다. 자료 가공에 1초가 걸리고, 인터넷 정보 획득에 5초가 걸린다. 이 두가지 일을 순차적으로 처리하면 자료를 다 가공하는 걸 기다리고, 인터넷 정보 획득을 또 다 기다린 후에 처리해야 한다. 6초가 걸린다. 그러나 이를 비동기로 처리하면 어떨까? 인터넷 정보 획득을 별도의 스레드로 분리하여 실행하고 이 작업이 진행되는 동안 자료 가공을 한다. 두가지 작업이 동시에 진행되므로 5초면 모든 작업이 완료된다. (물론 이 2가지 작업의 성질이 다르기 때문에 가능하다.)

다음 코드는 이와 유사한 작업을 하는 C# 코드이다. 더 자세한 설명은 MSDN2)을 참고한다.

// 정보 결합 메서드
async Task<string> MergeResultAsync()
{ 
    // 시간이 걸리는 인터넷 작업
    HttpClient client = new HttpClient();
    Task<string> internetTask = client.GetStringAsync("http://raychani.net");

    // CPU를 많이 활용하는 자료 가공 작업
    string localResult = ProcessData();

    // await 연산자를 만나면 이전 비동기 작업이 끝날 때까지 기다린다.
    // await 연산자는 Task의 결과인 string 값을 반환한다.
    string internetResult = await getStringTask;

    return localResult + internetResult;
}

더 쉬울지도 모를 다른 경우도 있다. 버튼을 클릭해서 인터넷에 있는 정보를 가져오는 메서드가 있을 때, 비동기로 코드를 작성하지 않으면 버튼을 누른 후 5초 동안은 다른 UI 작업을 할 수 없다. 그러나 이 기능을 이용하면 자동으로 비동기로 처리하여서, 다른 작업을 가능하게 해 준다.

다음 코드는 이런 경우에 사용할 수 있는 코드이다. 자동으로 자료형을 컴파일 타임에 결정한다. 컴파일 타임에 결정되므로 디버거에서도 즉시 자료형을 인식한다.

// 인터넷 자료 획득 메서드
async Task<string> MergeResultAsync()
{ 
    HttpClient client = new HttpClient();
    
    // UI 스레드가 다른 작업을 할 수 있게 해주어 효율이 향상된다.
    var internetResult = await client.GetStringAsync("http://raychani.net");
    
    // 작업 종료 후에 처리해야 할 코드가 있다면 복잡한 처리 없이 await 다음에 쓰면 된다.
    textView.Text = internetResult;

    return internetResult;
}

MFC에서 직렬화만 나오면 머리아파했던 기억이 난다. 그냥 내 맘대로 적당히 파일 형식 잡아서 쓰면 되지 저런 복잡한걸 왜 하냐고 생각했다.

오랜만에 간략한 DB가 필요하다 싶어서 찾다보니… 이런 저런 방법이 있었다.

  1. SQLite
  2. XML
  3. json

아마 순서대로가 가장 정석에 가까운 방법일 것이다. 하지만 테이블이 하나에 레코드는 많아야 1000개 정도로 예상되는 상황에서 새로 공부하긴 귀찮았다. XML도 피곤할 것 같고 요즘 많이 보이는 json을 써볼까 했다. 하지만…

C# XmlSerializer가 코드 단 5줄로 XML 파일을 만들어 버렸다. 심지어 자료형이 List<MyData>였는데도… 알아서 저장되더라. 당연히 읽는 것도 5줄로 끝난다. 다음은 참조 사이트이다.

C#에서 파일을 삭제하려 하면, 휴지통으로 보내지 않고 바로 지워버린다. 굳이 바로 삭제할 필요가 없어 휴지통으로 보내는 기능을 찾아보았더니 C#에서는 이 기능을 지원하고 있지 않았다. 구글검색을 통해 shell32.dll의 SHFileOperation을 직접 이용하는 방법이 소개되어 있다. 그러나 이 방법은 꽤 복잡한데다, 결국 0x53을 리턴하며, 실행에 실패했다. 리턴 코드의 의미는 잘못된 인자라는데, 그다지 잘못 된 부분이 없었다. 이 방법을 포기하고 다른 방법을 찾던 중 매우 간단한 방법을 찾을 수 있었다.3)

:!:윈도우7 k 64bit 비주얼 스튜디오 2005 C#.NET 2.0에서 다음 방법이 정상적으로 동작하였다.

  1. 먼저 참조에 Microsoft.VisualBasic을 추가한다.
  2. Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile, 또는 DeleteDirectory 매써드를 이용하여 삭제 할 수 있다.

이 기능을 자주 쓴다면 위임하는 매써드를 만들거나
using Microsoft.VisualBasic.FileIO
를 추가하면 된다.

DeleteDirectory의 경우 다음과 같은 문법을 가진다. string directory는 삭제하려는 디렉토리의 절대경로이며 나머지는 열거형이다. 어지간한 개발툴이면 사용 가능한 열거형을 자동으로 보여줄 것이다.

네임스페이스: Microsoft.VisualBasic.FileIO
어셈블리: Microsoft.VisualBasic(microsoft.visualbasic.dll)

public static void DeleteDirectory (
    string directory, // 삭제하려는 디렉토리의 절대경로
    UIOption showUI,
    RecycleOption recycle,
    UICancelOption onUserCancel
)

예)특별한 문제가 없으면, 별도의 창을 띄우지 않고, E:\test 폴더를 휴지통으로 보낸다.

Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(@"E:\test",
    Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
    Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin);

어차피 .NET기반이니 어디에 있든 상관 없을 수도 있지만, 왜 이 기능을 C#의 File이나 FileInfo 등에 직접 넣지 않았는지 모르겠다.

~~LINKBACK~~

~~LINKBACK~~


댓글을 입력하세요. 위키 문법이 허용됩니다:
C B I G V