What?
สังเกตุมั้ยว่าโปรแกรม client ส่วนมากเปิด 2 จอ พร้อมกันไม่ได้ user จะต้องหาโปรแกรมเสริมอย่าง sandbox มาใช้เพื่อเปิดโปรแกรม 2จอพร้อมกัน ยกตัวอย่างเช่น msn, skype, camfrog ถ้าเราเปิดโปรแกรมขึ้นมาแล้ว ดับเบิ้ลคลิ้กซ้ำจะเป็นการโฟกัสหน้าจอหลักที่เปิดอยู่แทนที่จะรันโปรแกรมใหม่
How to?
ตัวอย่างโค้ด System.Threading.Mutex ใน .NET framework
///อธิบายโค้ด../// The main entry point for the application. /// [STAThread] static void Main() { bool isReady; var mutex = new System.Threading.Mutex(true, "MyApplicationName", out isReady); if (!isReady) { //Console.WriteLine("Another instance is already running."); return; } GC.KeepAlive(mutex); //Run main form Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new UI.ReportForm()); }
class System.Threading.Mutex มาจากคำว่า "mutual exclusion" ทำหน้าที่เป็น synchronization object ประสานงานระหว่าง thread หรือการทำ Thread safe
var mutex = new System.Threading.Mutex(true, "MyApplicationName", out isReady);จากบรรทัดนี้เราสร้างตัวแปร mutex กำหนดชื่อ "MyApplicationName" ผ่าน constructor ทำให้ object mutex นี้ผูกติดกับ OS เพื่อใช้ตรวจสอบ Process ภายนอกโปรแกรม (interprocess synchroization) ว่ามี Mutex ชื่อนี้กำลังทำงานอยู่หรือไม่ (Note* ถ้าไม่กำหนดชื่อให้ mutex object จะมี scope แค่ภายใน current process เท่านั้น)
ถ้ามี mutex ชื่อ "MyApplicationName" กำลังทำงานอยู่ใน process ใดก็ตาม(เช็คในระดับ OS) out isReady จะได้ค่าเป็น false ดังนั้นเราก็สั่ง return หยุดการทำงานซะก่อนที่จะเปิดหน้าจอซ้ำ
GC.KeepAlive(mutex);ตรงนี้เป็นการป้องกัน Garbage Collector มาลบตัวแปร mutex object ของเราออกจากหน่วยความจำก่อนที่ user จะปิดโปรแกรม (GC จะคอยลบ object ไม่ได้ถูกเรียกใช้งาน)
Why/When? ทำไมต้องเปิดได้จอเดียว จำเป็นหรือไม่
ก่อนจะเขียนโปรแกรมต้องคิดถึง user ก่อนว่าทำไปเพื่ออะไร ไม่งั้น user จะโวยวาย(แล้วสุดท้ายก็เอา sandbox มาใช้เปิด 2จอ อยู่ดี)
1. transaction จำเป็นมั้ยที่แต่ละขั้นตอนต้อง commit ก่อน save มีการเช็ค session หรือสถานะการ login
2. client/server concurrent connection มีการจำกัดการเชื่อมต่อกับเซอฟเวอร์ (เช่น MSSQL license) หรือโปรแกรมเราใช้ bandwidth / performance
3. ถ้าลักษณะการทำงานเป็นแบบ MDI (multi document interface) ยกตัวอย่าง word, excel ไม่จำเป็นต้องล้อค mutex ครับอย่าลืมคิดถึง user เป็นหลัก
ยังมีอีกวิธีในการตรวจสอบจาก process table (running .exe) ว่าโปรแกรมถูกเปิดทำงานแล้วโดยใช้ System.Diagnostics.Process.GetProcessesByName() ใช้ได้เหมือนกันแต่ทำงานได้ช้ากว่า Mutex ที่ว่ามาลองศึกษาดูจากลิ้งค์อ้างอิงครับ
Reference :
- Michael A. Covington Ensuring that only a single instance of a .NET application is running
- Raymond Chen's blog A single-instance program is its own denial of service
ไม่มีความคิดเห็น:
แสดงความคิดเห็น