programing/C#

[C#]Timer 인자 전달.

쪽제비 2016. 8. 19. 10:43

수십개의 Sensor와 데이터를 주고 받아야 하는데 Server 입장이 아니라 Clinet로 Telnet 접속을 시켜줘야 하는 상황.

각자 다른 Interval로 접속해서 Data를 받아와야 해서 처음에는 Thread를 사용해서 Sleep을 쓸 생각이었으나...

이렇게 되면 일정 간격으로 log를 남길 수가 없다는 판단... 세션이 늘어날수록 지연될수도 있다는 의견..


그래서 Timer를 써야 하는데 인자 전달하는 방법을 찾아야 했다........




우선.. Timer가 3가지가 있다는... ?


1.System.Windows.Forms.Timer

2.System.Threading.Timer

3.System.Timers.Timer


출처 : http://blog.daum.net/starkcb/117


출처에 가보면 상세한 설명이 나와있음....


그러나 인자 보내는 방법이 없네 ?




그래서 더 찾아보니 방법이 있었다.


출처 : http://blog.naver.com/PostView.nhn?blogId=bluekms21&logNo=10177193993


자세히는 아니더라도 사용방법이 나왔다.

나는 System.Threading.Timer 를 사용해서 인자를 넘기는 방법으로 Timer를 생성할 것이다.


아래 부분은 위의 출처에서 가져온 내가 필요한 부분이다. 해보고 예제를 추가해보도록 하겠다...



System.Threading.Timer

역시 Thread가 짱짱맨이시다. 객체별로 다른 인자값을 넣어줘도 잘 돌아갔다.

인자값의 전달은 생성자의 2번째 인자에 object형으로 넣어주면 된다.

 

System.Threading.Timer timer = new System.Threading.Timer( proc, (object)value, 1000, 1000);

 

1) proc

System.Threading.TimerCallback 으로 인자로 object를 받고, 반환값이 void인 델리게이터이다.

 

2) (object)value

구지 캐스팅을 해주지 않아도 된다. (모든 객체는 object이므로...)

실행될 메서드에서 원래 집어넣었던 형태로 다시 캐스팅해서 사용하면 된다.

 

public void proc( object state )

{

    Console.WriteLine( (string)state );

}

 

3) 1000, 1000

시작전 대기시간과 간격이다. 3번째 인자값을 0으로 주면 즉시 실행하게 되는데

MSDN의 예제에도 10 ~ 1000 정도는 주고있는데 쓰레드가 다 완성된 뒤 시작하게 하려는 의도가 숨어있다.

Threading.Timer의 실행을 멈추려면

timer.Change( System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite ); 로 설정한다.

 


요건.. 내가 만든 예제, 조금 느린 감이 있긴한데... 흠.... 타이머를 다르게 가져가면 잘 안되는 듯 한데...


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

using System.Threading.Tasks;


namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            string value = "test";

            List<Timer> TimerList = new List<Timer>();

            for(int i = 1; i< 10; i++)

                TimerList.Add(new Timer(proc, (object)(value+i), 1000, 1000));


            Thread.Sleep(20000);

        }


        private static void proc(object state)

        {

            Console.WriteLine((string)state);

        }

    }

}