gFinger 손끝으로 만드는 세상

C# Program을 Real Time 성능에 가깝게





문제점


PLC를 사용하다가 보면 REAL-TIME 응답이 필요한 경우가 많이있습니다.

PLC의 경우 I/O 통신에서 극한적인 경우 1ms 정도, 보통 10~20ms 정도에 응답이 됩니다.

그러나 PC의 경우 하드디스크 억세스, 통신 연결 시도, 통신 실패, 가베지 컬렉션등이 발생하면 심한 경우 몇 초 이상의 딜레이, 지터 (JITTER)가 발생합니다.

PC를 PLC에 연결하여 사용하는 경우 PC는 OS 자체가 REAL-TIME이 아니기 때문에 속도를 요하는 통신 프로그램에서는 더욱 힘듭니다.

근본적으로 PC에 WINDOW는 REAL-TIME OS가 아니기 때문입니다.

따라서 REAL-TIME O/S하에서 PROCESS가 동작해야 해결될 문제입니다.

그래도 아래와 같은 코드를 넣으면 최대한 REAL-TIME에 가깝도록 되기는 합니다.

간단히 실험해 본 결과 10ms THREAD에서 시스템 부하를 조금씩 늘려 본 결과 10ms ~ 12ms 정도로 비교적 양호한 결과를 얻었습니다.



방법


아래와 같이 Program의 Priority를 올려주고 Thread의 Priority를 올려주는 방법을 사용하여 꽤 높은 Real-Time응답을 얻을 수 있었습니다.


 


///////////////////////////////////////////////
// For Real Time
//////////////////////////////////////////////
Process.GetCurrentProcess().PriorityBoostEnabled = true;
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

///////////////////////////////////////////////////////////
// For Real Time
///////////////////////////////////////////////////////////
PLCopenThread.Priority = ThreadPriority.Highest;


참조링크

https://stackoverflow.com/questions/12050925/increasing-thread-and-process-priority-to-reduce-execution-time-for-a-processor


'컴퓨터 이야기 > c#' 카테고리의 다른 글

visual studio 빌드 후 이벤트  (0) 2018.11.29
Text File Save Dialog  (0) 2018.06.09
File Name을 선택해서 Text 파일 읽기  (0) 2018.06.09
How to move and resize a form without a border?  (0) 2018.06.09
Form을 Drag해서 이동  (0) 2018.06.09



IF NOT EXIST c:\sssCom MD c:\sssCom
IF NOT EXIST c:\sssCom\dll MD c:\sssCom\dll
copy/y "$(TargetPath)"  "c:\sssCom\dll\*.*




Visual Studio에서 Build후 이벤트에 Command Line 명령어를 넣어 놓으면 방금 빌드한 파일을 원하는 폴더로 Copy 할 수 있다.



빌드 후 편집을 누르고 매크로를 누르면 $(TargetPath)등으로 프로젝트 폴더, 파일등의 정보를 삽입 할 수 있다.




Text File Save Dialog


       SaveFileDialog dlg = new SaveFileDialog();
            dlg.Title = "Save License File";
            dlg.Filter = "lic Files (*.lic)|*.lic";
            dlg.FileName = Application.StartupPath + "\\..\\..\\ssPlcADS.lic";
            if (dlg.ShowDialog() != DialogResult.OK) return;
            try
            {
                var sr = new System.IO.StreamWriter(dlg.FileName, false, System.Text.Encoding.UTF8);
                //Write the header
                sr.WriteLine(textBoxKey.Text);
                sr.Close();
            }
            catch
            {
                MessageBox.Show("Can't Write Key File");
            } 



File Name을 선택해서 Text 파일 읽기


            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Title = "Open License File";
            dlg.Filter = "License File (*.lic)|*.lic";
            dlg.FileName = Application.StartupPath + "\\..\\..\\" + filename;

            string ActivationKey;
            if (dlg.ShowDialog() != DialogResult.OK) return false;
            try
            {
                System.IO.StreamReader ObjReader = new System.IO.StreamReader(dlg.FileName);
                ActivationKey = ObjReader.ReadLine();
                ObjReader.Close();
            }
            catch (Exception ex) //General exception
            {
                MessageBox.Show(ex.Message);
                return false;
            } 


'컴퓨터 이야기 > c#' 카테고리의 다른 글

visual studio 빌드 후 이벤트  (0) 2018.11.29
Text File Save Dialog  (0) 2018.06.09
How to move and resize a form without a border?  (0) 2018.06.09
Form을 Drag해서 이동  (0) 2018.06.09
Program 2번 실행 방지  (0) 2018.06.06




- Form의 BorderStyle을 Node으로 하면 Border가 사라진다.
- 그러면 Resize 기능도 사라진다.
- 이런 경우 Grip을 실시간 추가 하고 OnPaint로 그려주면 Resize Grip을 이용 Resize가 가능하다.
- 단, Form을 다른 콘트롤이 꽉 채우게 되면 Resizing Grip이 Background로 그려지기 때문에 보이지를 않으므로 주의한다.

출처 :



        public FormMain()
        {               

            InitializeComponent();

            this.FormBorderStyle = FormBorderStyle.None;
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.ResizeRedraw, true);
        }
        private const int cGrip = 16;      // Grip size
        private const int cCaption = 32;   // Caption bar height;

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rc = new Rectangle(this.ClientSize.Width - cGrip, this.ClientSize.Height - cGrip, cGrip, cGrip);
            ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
            rc = new Rectangle(0, 0, this.ClientSize.Width, cCaption);
            e.Graphics.FillRectangle(Brushes.DarkBlue, rc);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x84)
            {  // Trap WM_NCHITTEST
                Point pos = new Point(m.LParam.ToInt32());
                pos = this.PointToClient(pos);
                if (pos.Y < cCaption)
                {
                    m.Result = (IntPtr)2;  // HTCAPTION
                    return;
                }
                if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip)
                {
                    m.Result = (IntPtr)17; // HTBOTTOMRIGHT
                    return;
                }
            }
            base.WndProc(ref m);
        }
        /////////////////////////////////////////// 


'컴퓨터 이야기 > c#' 카테고리의 다른 글

Text File Save Dialog  (0) 2018.06.09
File Name을 선택해서 Text 파일 읽기  (0) 2018.06.09
Form을 Drag해서 이동  (0) 2018.06.09
Program 2번 실행 방지  (0) 2018.06.06
Tray로 Form을 Icon화 하기  (0) 2018.06.06

 


        /// <summary>
        /// Form을 Drag 해서 이동
        /// </summary>
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();

        // Main Form을 마우스로 잡고 이동
        private void FormMain_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();  
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

        // menu Strip 부분을 마우스로 잡고 이동
        private void menuStrip1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }


'컴퓨터 이야기 > c#' 카테고리의 다른 글

Text File Save Dialog  (0) 2018.06.09
File Name을 선택해서 Text 파일 읽기  (0) 2018.06.09
How to move and resize a form without a border?  (0) 2018.06.09
Program 2번 실행 방지  (0) 2018.06.06
Tray로 Form을 Icon화 하기  (0) 2018.06.06