Friday, April 3, 2009

ThreadAbortException

ThreadAbortException เนี๋ย มั่วตั้งนาน

  • เค้าว่ามาว่าปัญหาส่วนใหญ่ของ Exception เนี๋ย จะมาจากการเรียก thread หนึ่งใน thread อื่นอ่ะ ไม่รู้ว่าอ่านที่เค้าที่เขียนถูกปะนะ



public static void ThreadLoadBar()
{
try
{
LoadBarForm progress = new LoadBarForm();
progress.ShowDialog();
}
catch (ThreadAbortException tae)
{
// Thread ถูก Abort
//Utility.MsgBoxInfomation("TWP: Aborted", null);
// บอกว่า ThreadAbortException ได้รับการ Handle แล้ว
Thread.ResetAbort();
}
}

Thread progressThread = new Thread(Utility.ThreadLoadBar);
progressThread.Start();

// ........................................

progressThread.Abort();


  • คือ ถ้าไม่ใช้ Thread ก็ไม่มีปัญหานะ แต่ที่ต้องแก้ปัญหาก็เพราะเราต้องใช้ Thread หว่า
  • ใช้ Thread มาช่วยทำโหลดบาร์อ่ะนะ
  • ที่งงมากๆ คือ แปลกตรงที่ เราไม่สามารถจะ จัดการ exception ตัวนี้ได้เลยหว่า try catch ครอบก็แล้ว
  • ที่แปลกเค้ามากๆ เลยคือ action ใน catch ThreadAbortException ทีงานนะ แต่ก็ขึ้น Exception
  • เพราะ บางครั้งก็เด้งขึ้นมา บางครั้งก็ไม่ปกติ ไม่รุ้ว่าปัญหาอยู่ที่อาไรหว่า
  • มั่วไปเรื่อยๆ ก็ไม่ได้ซะที สุดท้ายลงเอยที่ sleep ช่วยสักหน่อย

Thread progressThread = new Thread(Utility.ThreadLoadBar);
progressThread.Start();

// ........................................

Thread.Sleep(1000);
progressThread.Abort();

  • แต่เนี่ยอ่ะ หลังๆ ไม่เด้งขึ้นมาแล้วนะ exception เนี๋ย
  • คือ ตอนทดสอบชอบรัว เลยต้อง sleep ให้ thread แม่หน่อย
  • มั่วไปเรื่่อยๆ ก็น่ากลัวนะ อย่าลืม safe source ด้วยล่ะ มะงั้น จะไม่รู้ว่าเรามึนแก้อาไรไปมั่ง
  • เนี๋ยตอนแรกงงมากๆ ตูไปแก้อาไรตรงใหนฟะ ก่อนหน้านี้ยังรันได้อยู่เลย ทำไมขึ้นงี้ซะงั้น
  • แก้ไปเรื่อยสาเหตุคือ ใส่ Thread.ResetAbort(); ใน finally ซะงั้น มึนจริงๆ เรา เกือบแย่ซะแหละ

try
{
LoadBarForm progress = new LoadBarForm();
progress.ShowDialog();
}
catch (ThreadAbortException)
{
// Thread ถูก Abort
//Utility.MsgBoxInfomation("TWP: Aborted", null);
// บอกว่า ThreadAbortException ได้รับการ Handle แล้ว
Thread.ResetAbort();
}
finally
{
Thread.ResetAbort();
}


  • เอา thread.resetabort() หรือไม่ก็ทั้ง finally ออกไปซะ จบครับ - -''

Notes:
  • มั่วตามเค้าไปเรื่อยใส่เป็น ResetAbort() หรือ Join() รู้สึกว่าจะยังไม่รอดนะ หรือ รอดอ่ะไม่แน่ใจ
  • หรือสาเหตุ คนละอย่างกันหว่า แต่โค้ดเราก็น่าจะมาจาก thread ไปเรียก thread เลยเกิดนะ exception ตัวนี้อ่ะ
  • แต่คิดว่า ถ้าทำตาม เค้า ก็น่าจะแก้ปัญหาเรื่องนี้ได้มั่ง ที่แก้ไม่ได้อาจเป็นที่ตัวเอง อ่านไม่รู้เรื่อง T_T
  • คิดว่าการวาง try catch ThreadAbortExeption น่าจะวางที่ loop แสดงโหลดบาร์วิ่งไปเรื่อยๆ ไม่หยุดน่าจะวางที่นี้แหละ สงสัยเราจะวางผิดที่ ดูที่นี้แล้ว เค้า จะวางครอบ while() หว่า ^^'

Solved


private void LoadBarForm_Load(object sender, EventArgs e)
{
//loadFormTemp = this;

try
{
t.Start();
}
catch (Exception)
{
Thread.ResetAbort();
}
}

private void RunProgressBar()
{
//if (InvokeRequired) // Line #1
//{
// this.Invoke(new MethodInvoker(RunProgressBar));
// return;
//}

try
{
for (int i = 0; i < 100; i++)
{
for (int j = progressBar1.Minimum; j < progressBar1.Maximum; j++)
{
progressBar1.Value = j;

Thread.Sleep(10);
}

for (int k = progressBar1.Maximum; k > progressBar1.Minimum; k--)
{
progressBar1.Value = k;

Thread.Sleep(10);
}
}
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
//throw;
}
catch (Exception)
{ }
}


  • เท่าที่สังเกตวางครอบ t.start(); ก็ไม่หายนะ ต้องวางครอบ for infinity เราซะเลย ^^' รู้สึกจะดีขึ้น
  • วางตรงนี้อ่ะ น่าจะถูกต้องแหละ

สรุปผล
  • ครอบ try catch ที่ loop infinity และ Thread.ResetAbort(); ซะ
  • โง่จริงๆ ไม่เข้าใจเรื่อง threading เล้ย แล้วเมื่อใหร่จะเข้าใจล่ะเนี๋ย เวงจริงๆ เรา - -'
  • ครอบ t.start(); ไว้ด้วย กันเหนียวดี

อ่านเพิ่มเติม

No comments:

Post a Comment