ShadowWares Forum

Programming (Languages) => C# => ข้อความที่เริ่มโดย: ShadowMan ที่ กันยายน 26, 2016, 08:20:07 am



หัวข้อ: Thread Updates GUI and Form Closed
เริ่มหัวข้อโดย: ShadowMan ที่ กันยายน 26, 2016, 08:20:07 am
การ Update UI จาก Thread ได้เขียนบทความสั้นไว้หลายตอนแล้ว แต่ยังไม่ได้เขียนเกี่ยวกับปัญญหาที่อาจจะเกิดขึ้นเมื่อใช้ Thread ในการ Update UI แบบต่อเนื่อง และ Form หรือ UI Component ตัวที่ถูกเข้าถึงจาก Thread ถูกทำลายเช่น Form ถูกปิด (เมื่อ Form ถูกปิด UI ที่อยู่บน Form จะถูกทำลายด้วย) ในขณะที่ Thread กำลังรันอยู่

ตัวอย่างปัญหา:
(http://upic.me/i/4n/10capture.png)

วิธีที่ 1 ใช้ try/catch:
เมื่อ Form ถูกปิด object ต่างๆ จะถูกทำลาย การที่ Thread พยายามเข้าถึงสิ่งที่ถูกทำลายไปแล้วย่อมส่งผลให้เกิดปัญหา
แก้ได้โดยทำการหยุดการทำงานของ Thread โดยใช้ Abort()
IsDisposed จะเป็น false เมื่อ Form ถูกปิด/ทำลาย จึฃนำมาใช้เป็นเงื่อนไขสำหรับ wile() ได้ รายละเอียดตาม code ต่อไปนี้
Code: (c-sharp)
    public partial class FormMain : Form
    {

        Thread MainThread;

        public FormMain()
        {
            InitializeComponent();
            MainThread = new Thread(MainLoop);
            MainThread.Start("Hello");
        }

        void MainLoop(Object obj)
        {

            while (!IsDisposed)
            {
                try
                {
                    Invoke((MethodInvoker)(() => {
                        /* Access GUI components here */
                    }));
                }
                catch (ObjectDisposedException)
                {
                    MainThread.Abort();
                }
                Thread.Sleep(20);
            }
            MainThread = null;
        }
    }




วิธีที่ 2 ทำการ override OnClosing
ในขณะที่ Form กำลังถูกปิด (กระบวนการทำลายกำลังทำงาน) OnClosing() จะถูกเรียก จึงสามารชิงทำลาย Thread เสียก่อนได้ โดยใช้ Abort() ตามตัวอย่างต่อไปนี้
Code: (c-sharp)
    public partial class FormMain : Form
    {

        Thread MainThread;
        bool Running;

        public FormMain()
        {
            InitializeComponent();
            MainThread = new Thread(MainLoop);
            MainThread.Start("Hello");
        }
        void MainLoop(Object obj)
        {
            Running = true;
            while (Running)
            {
                Invoke((MethodInvoker)(() => {
                    /* Access GUI components here */  
                }));

                Thread.Sleep(20);
            }
            MainThread = null;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            MainThread.Abort();
            base.OnClosing(e);
        }
    }





หัวข้อ: Re: Thread Updates GUI and Form Closed
เริ่มหัวข้อโดย: Frideborg ที่ กรกฎาคม 09, 2018, 11:36:00 am
Form ถูกปิดนี้เองผมก็ว่าทำไม่ได้