posted by 방랑군 2012. 1. 21. 23:41

특정 클래스가 IEnumerable인터페이스를 구현했다면 IEnumerator를 사용해서 내부의 데이터를 순방향으로만 접근할 수 있는 기능을 가진 것이다.

IEnumerator형으로 얻은 객체는 읽기전용 커서(Cursor)를 제공하고 있으며, 데이터의 집하벵 대한 순방향으로 검색할 수 있다.


IEnumerable인터페이스에는 GetEnumerator()함수를 사용해서 IEnumerator를 얻어서 작업을 한다.

IEnumerable인터페이스는 내부에 GetEnumerator()추상함수를 포함하고 있으며, 이 함수를 이용해서 IEnumerator의 객체를 얻을 수 있다.

IEnumerator는 현재 커서 위치에서 데이터를 추출하는 기능을 지원하며 순방향으로 검색기능을 제공하는 것은 항연한 소리이다.

커서를 데이터 집합의 시작점으로 돌리는 기능도 제공한다.


Array클래스는 IEnumerable인터페이스를 구현하였기 때문에 IEnumerator를 사용할 수 있다.

다음 예제는 배열에서 IEnumerable인터페이스를 사용하는 방법을 보여주고 있다.


using System;

using System.Collections;


public class IEnumerableTest

{

public static void Main()

{

string[] authors = { "A", "B", "C", "D", "E", "F" };

IEnumerator e = authors.GetEnumerator();

while (e.MoveNext())

{

Console.WriteLine(e.Current);

}

}

}




IEnumerator객체를 얻기 위해서는 GetEnumerator()를 사용하면 된다.

모든 배열은 IEnumerator 인터페이스를 구현하고 있기 때문에 배열에 대해 GetEnumerator()함수를 호출할 수 있다.


IEnumerator객체를 얻은 후 순방향으로 순회하기 위해서 while루프에서 MoveNext()함수를 호출하면 된다.

그리고 MoveNext()로 커서를 움직인 후 커서가 위치한 곳의 데이터를 추출하기 위해서 Current 속성을 이용한다.

이 때 Current의 타입은 Object형이다.


Current포인터를 컬렉션의 처음부분앞에 있는 정의하지 않은 값으로 다시 설정할 때는 Reset()을 호출한다.

Reset()을 호출한 후 Current로 접근하기 전에 MoveNext()를 호출해야 한다.

이유는 처음에는 Current참조가 정의되지 않기 때문이다.


IEnumerator객체가 컬렉션의 마지막 위치에 있을 때 MoveNext()함수를 호출하면 false를 반환한다.

따라서 컬렉션 내의 모든 데이터에 대해 MoveNext()함수가 true를 반환하는 동안 루프를 수행하면서 false가 반환되면 빠져나오는 방법으로 데이터를 검색할 수 있다.

posted by 방랑군 2012. 1. 21. 22:46

출처 :  http://blog.naver.com/prokyhsigma?Redirect=Log&logNo=120109045619

스레드함수.cs

class ThreadTest
{
// 스레드 동기화 및 일시정지, 재시작
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private ManualResetEvent _pauseEvent = new ManualResetEvent(false);

private Thread m_thread;


public ThreadTest()
{
m_thread = new Thread(new ThreadStart(threadFunc));
m_thread.Name = "test";
m_thread.IsBackground = true;
m_thread.Start();
}


private void threadFunc()
{
int i = 0;

while(_pauseEvent.WaitOne())
{
System.Diagnostics.Trace.WriteLine(i.ToString());
i++;
Thread.Sleep(1000);

}
}


// --------------------------------------------------------------------------------
// 스레드 일시정지
// --------------------------------------------------------------------------------
public void pause()
{
_pauseEvent.Reset();
}//end pause()

// --------------------------------------------------------------------------------
// 스레드 재시작
// --------------------------------------------------------------------------------
public void resume()
{
_pauseEvent.Set();
}//end resume()

// --------------------------------------------------------------------------------
// 스레드 종료 준비, 동기화 이벤트 처리
// --------------------------------------------------------------------------------
public void readyEndThread()
{
_shutdownEvent.Set();
_pauseEvent.Set();
}//end endThread()
}
}

메인.cs

static void Main(string[] args)
{
ThreadTest test = new ThreadTest();
test.resume();

Thread.Sleep(3000);
test.pause();

Thread.Sleep(3000);
test.resume();

Thread.Sleep(30000);
}

메인 클래스에서 스레드 함수를 자유롭게 통제 가능해진다.

결과> 1, 2, 3 출력 후 3초 뒤 다시 4, 5, 6 다시 3초뒤 나머지 30초동안 뒷 숫자가 출력이 된다.

[ 주의점 ]

1. 이벤트 초기값 false로 스레드를 처음부터 일시정지 시켜놓을 수 있다. true면 바로 시작.

2. 반복문의 조건을 _pauseEvent.WaitOne()) 으로 두어서 신호를 반복문 제어값으로 해놓는다.