레이블이 csharp인 게시물을 표시합니다. 모든 게시물 표시
레이블이 csharp인 게시물을 표시합니다. 모든 게시물 표시

2010년 10월 28일 목요일

yield 키워드를 이용한 루프-데이터 반환 최적화

.NET 2.0 부터 있던 키워드이나, 사실상 잘 이용 안되고 있었던 키워드가 있었으니 바로 yield 이다.
yield는 원래 Ruby 에 있던 개념이었는데 제한적으로 C#에서 언어용으로 차용하게 되었다.
하지만 MSIL 수준에서의 지원은 아니고  컴파일시 C# 컴파일러가 자동으로 Code를 생성해준다.
 
 
yield는 return, break 과 같이 사용하며,  yield를 쓰면 루프에서 원하는 조건에 맞는 데이터들의 리스트를 IEnumerable 형태로 얻어올수 있다.
그러니까, 만일 루프를 돌면서 어떤 목록에서 특정 아이템들을 뽑아 따로 리스트를 만들고 싶다면 루프 이전에 컬렉션을 하나 만들고 이 컬렉션에 값을 넣는 코드를 삽입해야 한다.
하지만 yield는 이를 단 한줄로 해결해 준다.

[code csharp]
public class List
{
        //using System.Collections;
        public static IEnumerable Power(int number, int exponent)
        {
                int counter = 0;
                int result = 1;
                while (counter++ < exponent)
                {
                        result = result * number;
                        yield return result;
                 }
        }
        
        static void Main()
        {
                // Display powers of 2 up to the exponent 8:
                foreach (int i in Power(2, 8))
               {
                        Console.Write("{0} ", i);
               }
        }
}
[/code]


 Yield의 구현은 다음 아티클을 참조 : 내부적으로 루프 코드를 State 머신 형태로 변경하여 데이터를 뽑아낸다.
 
Yield는 동일한 기능을 구현하는 코드보다 성능이 더 좋은편이다.
 
 
 
이 글은 스프링노트에서 작성되었습니다.

2010년 6월 19일 토요일

VisualBrush와 RenderTargetBitmap

 

WPF에서 쓰이는 화면에 보이는 UIElement들은 제 각각 Visual 이라는 객체를 상속받아 만들어지는데 이들은 스스로 자신을 화면에 그릴수 있는 기능이 있다. 따라서 Visual의 이 기능을 이용하여 다음과 같이 재밌는 일을 할수 있다. (미리보기등을 이러한 방법으로 만들수 있다.)

 

Clone 화면 만들기

VisualBrush를 이용하면 Visual의 화면 이미지를 실시간으로 복제하여 Brush를 필요로 하는 위치에 그려주게 된다. 내부적으로 브러시의 원본 객체의 surface 를 복제함으로서 이루어진다.

 

 

  1. VisualBrush brush = new VisualBrush(this.DrawingCanvas);
  2. Rectangle rect = new Rectangle();
  3.  
  4. rect.Width = this.DrawingCanvas.ActualWidth;
  5. rect.Height = this.DrawingCanvas.ActualHeight;
  6. rect.Fill = brush;

    Window wd = new Window();
  7. wd.Content = rect;

 

 

마치 클론 화면을 쓰는 것처럼 쉽게 복제된 화면을 여러개 만들수 있다. 원본 화면에서 뭔가 일어나면 다른 화면에서도 똑같이 발생한다.



화면의 특정부위 스샷찍기

화면을 복제하는 것보다, 그때 스샷을 찍고 싶을때가 있다. 특히 원하는 컨트롤 또는 부위에 대해서. 이런때엔 RenderTargetBitmap을 이용하면 간단히 해결된다. 이때엔 별도의 Bitmap이미지를 생성한후 객체의 Visual 화면을 BitBlt 하여 복제한다. 단, 이때엔 새로만들어지는 비트맵의 색상 또는 dpi를 지정해 줄수 있는데 이를 이용하여 성능을 조절할 수 있다.

 

 

  1. RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.DrawingCanvas.ActualWidth, (int)this.DrawingCanvas.ActualHeight, 100, 100, PixelFormats.Default);
    rtb.Render(this.DrawingCanvas);

    Window testWin = new Window();
    testWin.Width = this.DrawingCanvas.ActualWidth;
    testWin.Height = this.DrawingCanvas.ActualHeight;
    (testWin.Content as Image).Source = rtb;

    testWin.Show();

 

 

현재 화면을 복제하고, 원본 화면이 바뀌더라도 현재 화면을 유지한다.

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.