[AS3 Worker] Thread Test

 

드디어 As3 에 Worker 라는것이 생겼다.

바로 Thread 이다.

하지만 , 방법이 조금 지저분 하다.

실행되고 있는 바이트 코드를 그대로 복제하여 ,백그라운드에서 실행하고 그 결과를 메시지 체널 형태로 주고 받는다.

정확한 Thread 의 개념 보다는 .NET 의 BackgroundWorker 쯤으로 생각하면 될듯하고

쓰레드를 직접실행할 클래스 형태가 필요하다.

 

아래의 ThreadManager 는 구차한 Worker 생성과정을 미리 생성하고 Thread 객체를 관리하는 매니저 역할이다.

또하나의 Worker1 클래스는 쓰레드 개체가 생성하게될 , 즉 쓰레드가 수행할 내용이다.

아래의 실험은 같은 개체를 동시에 실행 하였을때 쓰레드 블럭킹이 발생하는지 실험하는 코드이다.

 

* ThreadManager

 
package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    
    import jjongun.threadWorker.Thread;
    import jjongun.threadWorker.ThreadEvent;
    import jjongun.threadWorker.ThreadManager;
    
    public class TestThread3 extends Sprite
    {
        private var thread1 : Thread;
        private var thread2 : Thread;
        public function TestThread3()
        {
            ThreadManager.Init(this.stage);
            
            thread1 = ThreadManager.getInst().createThread(Work1);
            thread2 = ThreadManager.getInst().createThread(Work1);
            
            thread1.addEventListener(ThreadEvent.RECEIVE , receive);
            thread2.addEventListener(ThreadEvent.RECEIVE , receive);
            
            thread1.start();
            thread2.start();
            
            stage.addEventListener(KeyboardEvent.KEY_UP , stageKup);
        }
        
        protected function stageKup(e:KeyboardEvent):void
        {
            if(e.keyCode == Keyboard.A)
            {
                trace("A");
                thread1.send(Work1.F1);
            }
            else if(e.keyCode == Keyboard.S)
            {
                trace("S");
                thread2.send(Work1.F2);
            }
        }
        
        protected function receive(e:ThreadEvent):void
        {
            if(e.currentTarget == thread1)
            {
                trace(e.receiveData);
            }
            else if(e.currentTarget == thread2)
            {
                trace(e.receiveData);
            }
        }
    }
}

 

 

 

 

package
{
    import flash.utils.getTimer;
    
    import jjongun.threadWorker.AbsThreadWorker;
    
    public class Work1 extends AbsThreadWorker
    {
        public function Work1()
        {
            super();
        }
        
        public static const F1 : String = "F1";
        public static const F2 : String = "F2";
        protected override function threadMessage(command:*):void
        {
            trace("command " , command);
            if(command == F1)
            {
                f1();
            }
            else if(command == F2)
            {
                f2();
            }
        }
        
    
        
        private function f1():void
        {
            trace("start _ f1 " , getTimer());
            
            var b : Boolean = true;
            var cur : Number = getTimer();
            while(b)
            {
                if(getTimer() - cur > 3000)
                {
                    b = false;
                }
            }
            
            trace("end _ f1" , getTimer());
        }
        
        private function f2():void
        {
            trace("start _ f2 " , getTimer());
            
            var b : Boolean = true;
            var cur : Number = getTimer();
            while(b)
            {
                if(getTimer() - cur > 3000)
                {
                    b = false;
                }
            }
            
            trace("end _ f2" , getTimer());
        }
    }
}

 

결과 블럭킹이 전혀 발생하지 않았고 상상했던 Thread의 역할을 충분히 수행해 주었다.

 

주의할점은 현재 시점으로 11.4 버전 -swf-version=17 만 가능하다.

혹 그 윗버전의 SDK 로 시도 해보았지만 작동이 안된다. 이유는 모른다. 버그 같다. 어도비 포럼에도 질문만 있을뿐 답이 없다.

머 ,, 곧 해결 되겠지만 , 현재 11.4 버전 만 된다. 버전 체크를 하여 수행하여야 하겠다.

 

'AS3' 카테고리의 다른 글

FLA Auto build utility for flashbuilder developer  (2) 2014.02.22
[AS3] asmx 사용하기  (87) 2013.01.12
[AS3 Worker] Thread Test  (2920) 2012.11.15
간단한 AS3 바이트 버퍼 나누기  (110) 2012.03.09
[Multitouch on 3D World]  (92) 2012.01.17
[Base64]  (282) 2011.12.19
Yamecoder 야매코더_
tags : AS3, Thread, worker
AS3 2012.11.15 23:38

[XNA , WPF] XNA 에서 코드레벨로 WPF 생성하기




필요한 레퍼런스는
 
System.Windows.Presentaion
System.Xaml
PresentationCore
PresentationFramework

이고  필요한 using 은

using System.Threading;
using System.Windows;
using System.Windows.Controls;

되겠다.


Created with colorer-take5 library. Type 'csharp'
XNA , Game1.cs 중 일부

        Texture2D tex;
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            tex = Content.Load<Texture2D>("logo2");
            this.Window.Title = "currentThread :" + Thread.CurrentThread.ManagedThreadId;
            
            //[0] 새로운 wpf 어플을 생성하기 위해 새로운 스레드 생성 , 스레트타입은 STA
            Thread t = new Thread(startThread);
            t.ApartmentState = ApartmentState.STA;
            t.Start();
        }
        void startThread()
        {
            //[1] Application 객체를 선언하고 생성
            Application app = new Application();
            //[2] StartUp 이벤트를 건다.
            app.Startup += new StartupEventHandler(app_Startup);
            //[3] 그리고 시작!
            app.Run();
        }

        void app_Startup(object sender, StartupEventArgs e)
        {
            //[4] 새로운 윈도우를 생성한다
            Window win = new Window();
            win.Width = 300;
            win.Height = 300;
            win.Title = "currentThread :" + Thread.CurrentThread.ManagedThreadId;
            //[5] 새로운 윈도우를 표시한다
            win.Show();

            Button bt = new Button();
            bt.Content = "XNA 에서 WPF 생성��기";
            win.Content = bt;
        }

역시나 윈도우폼과 마찮가지로 STA 타입의 스레드가 필요하다.
그러나 윈폼과 Application 의 사용법이 다른점에 주의! (그냥 Application.Run 하면 안된다.)

또한 닷넷4.0의 경우 System.Xaml 을 필히 참조 시켜줘야 겠다. 
Yamecoder 야매코더_
XNA 2011.02.01 16:03

[new Thread in new Form] 새로운 쓰레드 안에 새로운 윈도우폼

무작정 쓰레드를 생성하여 폼을 생성한다면... 
 
Thread t2 = new Thread(sample);
        t2.Start();
...
        private void sample()
        {
            Form n = new Form();
            n.Show();
        }
바로 폼이 깜빡 거리고 만다. 해당쓰레드가 바로 죽기 때문이다.
새로운 폼은 새로운 어플리케이션으로 생성해야 한다.
 
 
 
 
 
Thread t2 = new Thread(sample);
        t2.Start();
...
        private void sample()
        {
            //Form n = new Form();
            //n.Show();
Application.Run(new Form2());
        }
 
 주의할점은 Application.Run 앞에 모든 명령이 와야 한다.
해당 쓰레드는 Application을 기점으로 돌고 있기 때문에 Application 뒤에 명령이 온다면,
Application 이 종료된다음에 실행된다. while 문과 같다고 생각하면 되겠다.
 
Dispose 를 구현한다면 Application 뒤에 오는것도 나쁘지 않겠다.
 
ex> 
 
Application.Run(...);
Consol.writeLine("해당 어플리케이션이 종료되었습니다.");
 
 
 
 
 
더욱 안전한 방법을 원한다면 
BackgroundWorker 를 사용하는 방법도 있다.
 
보기
 
구현방법은 역시 같다.
Yamecoder 야매코더_
C# 2011.01.19 17:18

[Simple Text Writer V0.1] 간편한 파일 쓰기 어플


간편한 파일 쓰기 어플



client code (AS3)

flush 규칙!


         파일경로(filePath):::내용(content) + "\n"

(':::' 요걸로 파일경로와 내용을 구분합니다.)


ex >> "c:\\sampleFolder\\childFolder\\content.xml"
         +":::
         +xml.toString()
         +"\n";


그냥 자기 컴퓨터에서 돌아가는 로컬용 입니다.(웹은 당연 안돌아가겠죠)
대용량은 테스트 안해봤습니다.
하루 종일 돌려보진 않았습니다.
피드백은 덧글로..
버전업은 할수 있을지. ,, 과연 = =;
옵션도 넣고 하려 했지만.. 일을 줄이기 위해 만드는건데, 이게 더 일이 될것 같아서 딱 필요한것만 구현했습니다.
Yamecoder 야매코더_
C# 2010.12.04 02:35

[BackGroundWorkerTEST] Sync , Async , Thread





주요 Code




MSDN
http://msdn.microsoft.com/ko-kr/library/system.componentmodel.backgroundworker(v=VS.90).aspx?appId=Dev10IDEF1&l=KO-KR&k=k(EHINVALIDOPERATION.WINFORMS.ILLEGALCROSSTHREADCALL);k(TargetFrameworkMoniker-".NETFRAMEWORK&k=VERSION=V3.5");k(DevLang-CSHARP)&rd=true




Created with colorer-take5 library. Type 'csharp'

//sync
        private void testCodeSync()
        {
            using (System.Net.WebClient wc = new System.Net.WebClient())
            {
                wc.DownloadFile(streamPath, "test_"+checkTime.ToString()+currentState+".tmp");
            }
            stateTx.Text = currentState + " :: done";
        }


        //async
        private void testCodeAsync()
        {
            using (System.Net.WebClient wc = new System.Net.WebClient())
            {
                wc.DownloadFileAsync(streamPath, "test_" + checkTime.ToString() + currentState + ".tmp");
            }
            stateTx.Text = currentState + " :: done";
        }
        

        
        //################
        //backgroundworker
        BackgroundWorker bw = new BackgroundWorker();
        void BGWorker()
        {
            //bw = new BackgroundWorker();
            bw.RunWorkerAsync();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }
        

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //RunWorkerCompleted 이벤트 안에서는 윈폼 스레드로 돌아와 안전��게 컨트롤 할�� 있다.
            stateTx.Text = currentState + " :: done";
            bw.Dispose();
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            using (System.Net.WebClient wc = new System.Net.WebClient())
            {
                wc.DownloadFile(streamPath, "test_" + checkTime.ToString() + currentState + ".tmp");
            }
            //에러! : 크로스 스레딩 ( 스레드가 다르다 )
            //stateTx.Text = currentState + " :: done";
        }
인터넷 속도가 빠를경우 테스트가 잘 되지 않지만 Async 도 처음에 실행할때는 약간의 딜레이가 생긴다
sync 는 항상 딜레이가 생긴다.
테스트 타겟은 구글의 메인페이지 이다.
Yamecoder 야매코더_
C# 2010.12.04 02:26

[C# Thread]종료시 프로세스 죽이기



Thread 를 사용하고, 프로그램을 그냥 종료 하면 작업관리자에 프로세스가 완전히 죽지 않는

경우가 생긴다.

이때 C#의 ApplicationExit 이벤트로 처리해주어야 한다.




Application.ApplicationExit += new EventHandler(Application_ApplicationExit);


///....///



          void Application_ApplicationExit(object sender, EventArgs e)
        {
            try{
            server.Stop();
            if(clinet != null)
                clinet.Close();
            writer.Close();
            reader.Close();
            serverThread.Abort();
            }catch{}
        }
여기서 server는 TCPListener  이고 Client 는  TCPClinet 이고, writer 와 reader 는 

StreamWriter 와 StreamReader 이다.

여기서 serverThread 가  Thread   이다.


이런식으로  app 가 종료되는 시점을 파악하여 여지가 될만한것들을 모두 삭제하여야 한다.
 
Yamecoder 야매코더_
C# 2010.12.04 00:16

[BeginInvoke] Delegate 로 스레드에 매개변수 전달하기



보통 스레드를

Thread t = new Thread( new ThreadStrat(Method) );

의 형태로 사용 하는데 Method 에 매개변수를 전달하지 못한다는 제약이 있다.

그래서  delegate 의 BeginInvoke 메소드를 통해 스레드를 작성해보자.




Created with colorer-take5 library. Type 'csharp'

/*
 * SharpDevelop으로 작성��었습니다.
 * 사용자: jjongun
 * 날짜: 2010-02-04
 * 시간: ��후 4:48
 * 
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Diagnostics;

namespace testSockerServer
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        //스레드로 만들 델리게이트 선언
        delegate void runDele(string str);
        public MainForm()
        {    
            InitializeComponent();
            
            Trace.WriteLine("��제 메인 스레드 id: " +Thread.CurrentThread.ManagedThreadId);
            
            //델리게이트 생성
            runDele d = new MainForm.runDele(this.initServer);
            //BeginInvoke 로 매개변�� 전달
            d.BeginInvoke("string value",null,null);
        }
        
        private void initServer(string str)
        {
            Trace.WriteLine("델리게이트로 만든 스레드 id: " +Thread.CurrentThread.ManagedThreadId +"\n"
                           +str);
        }
    }
}

/**
 *   출력 : 
 * 
 *  ��제 메인 스레드 id: 1
 *    델리게이트로 만든 스레드 id: 3
 *     string value
 *  
 * */
Yamecoder 야매코더_
C# 2010.12.04 00:11
Powerd by Tistory, designed by criuce
rss