Nine MVP's Blog

28/12/2006

Blog: มาทำ Auto Hide Window แบบ TaskBar กันเถอะ (C#)

Filed under: ลากมาตอบ — Nine MVP @ 1:49 pm

 

จะปีใหม่แล้ว งานต่าง ๆ ก็น้อยลง คนทำงานก็เบามือ ๆ ลง เลยว่างนิดหน่อย แวะมาทำโปรแกรมเล่น ๆ ให้เสร็จฝากเพื่อน ๆ
 
เป็น window application ครับ เป็นตัวอย่างที่เขียนโดยใช้ C#
สมัย .NET 1.1 จะทำหน้าจอแบบนี้คงต้องใช้ Win32 API กัน
แต่หลัง .NET 2.0 ออกมาก็ลด code ได้ได้เยอะครับ สั่งแค่นิดหน่อยก็ได้งานแล้ว
และ code อีกส่วนนึงจะเป็นการทำงานแบบ multi thread โดยใช้ threadpool class เข้ามาช่วยในการทำ autohide ของ window ครับ
code ส่วนสำคัญ ๆ ผมจะ Comment ไว้ให้หมดแล้วนะครับ
 
ก็ลองเอาไปประยุกต์ต่อกันเองนะครับ คิดว่าน่าจะมีประโยชน์บ้าง 
 
อืมลองดูตามรูปข้างล่างนะครับ แถบสีฟ้า ๆ  จะเป็น window form นั้นเอง จะหุบ ๆ โผล่ ๆ หุหุ
 
 
 
 
 
 
 

Download Source Code Here!!

http://nine.greatfriends.us/AutoHideForm.rar

 
 
ใครไม่เข้าใจ code บรรทัดไหนก็ ถามมาได้นะครับ
หรือใครอยากได้ feature อะไรเพิ่ม ถ้ามีเวลาจะเพิ่มให้ครับ
 
ปล. ตอนนี้ทำ align window ได้ 2 แบบ คือ Top และ Left ครับ

Advertisements

20/12/2006

ถามเกี่ยวกับ webservice และ transaction

Filed under: Computers and Internet — Nine MVP @ 5:27 pm

ถามเกี่ยวกับ webservice และ transaction

คือสมมติว่า ผมมี webservice อยู่ 2 ตัว และ database server อยู่ 2 ตัว โดย webservice1 จะติดต่อกับ DB1 และ
webservice2 จะติดต่อกับ DB2
จากนั้นผมก็มี application อยู่ตัวนึงซึ่งทำการเรียก webservice1
จากนั้น webserice1 ก็จะทำการ query data อะไรบางอย่างจาก DB1 แล้วส่งไปให้ webservice2
จากนั้น webservie2 ก็จะทำการ insert ข้อมูลลง DB2 แล้วส่งค่าอะไรบางอย่างกลับไปให้ webservice1
จากนั้น webservice1 ก็จะทำการ update status ตามที่ได้รับจาก webservice2

ดังภาพข้างล่าง

 
  
 
application call –> Webservice1DB1              
                                                          ———————->>>    ส่ง data ไป insert
                                                                                                Webervice2DB2
                                                          <<<———————-    ส่ง data กลับไปเพื่อ update status  
                            Webservice1 — DB1  ถ้าเกิด error ตรงนี้
app <—-  รับ message return
 
คำถาม
1. เราสามารถทำการ Rollback สิ่งต่างๆ ที่เราทำไปทั้งใน DB1 และ DB2 ได้หรือไม่
2. ถ้าทำได้ใช้วิธีการอย่างไร

รบกวนหน่อยครับ  ( เหตุการณ์นี้ ยังไม่เกิด ขึ้นจริง แต่ผมกลัวว่า ไม่นานมันจะต้องเกิด เลยมาถาม )

 

  LaLaLa  
 

1. ทำได้ครับ

2. ทั้ง 2 WebService ต้อง ใช้งาน WS-Transaction, WS-Coordination
    ซึ่งสำหรับ MS Plateform ไม่ง่ายเท่าไหร่นัก  = =’ ไว้จะพยายามทำ example มาให้ดูครับ รอก่อนนะ หุหุ

  Nine (นาย)  
ตอบคุณ มี่ นะครับ
คือผมต้องการที่จะควบคุม ความถูกต้องของข้อมูลครับ  ไม่เกี่ยงวิธี 
ขอให้ง่าย performance ดี คือผม ไม่ค่อยจะมีความรู้เท่าไหร่อ่ะ แบบว่ารู้น้อย
ซึ่งปกติแล้ว ผมก็ใช้
 
try
{
   BeginTransaction()
   —————– code————-
   Commit()
}
catch(Exception ex)
{
  RolllBack()
}
 
ผมเลยเรียกมันว่า Transaction

ยังงัยก็รบกวนด้วยนะครับ ^^"

 
 

  LaLaLa  

ถามเพิ่ม

1. WS อยู่บน server เครื่องเดียวกันหรือว่าแยกเครื่อง
2. DB ——————-"—————————–
3. หาก ws แยก server กันอยุ่ แล้ว Network แยกจากกันหรือไม่

  Nine (นาย)  
ทุกอย่าง ถูกแยกออกจากกัน หมดเลยครับ

เหมือนเป็นการ ส่งต่อ project อ่ะ พี่เชน (phase 2 phase 3 คงพอนึกออกนะครับ)


  LaLaLa  
REPLY #6 (30728)

งั้นก็พอจะบอกได้เลยว่า Client ที่เรียก -> WS1 Transaction ไม่สามารถ cover ไปถึง WS2 นะ
เพราะ WebService โดย nature ของมันคือเป็นแบบ StateLess  ทำอะไรไปแล้วก็จำไม่ได้ เป็นปลาทอง
ต้องทำให้ WS1, WS2 ใช้ WS-TX, WS-Coor. ตามที่บอกไปข้างบนนั่นหละครับ
 
แต่จะทดสอบ TransactionScope ให้ก่อนนะ
โดยการเรียก WS1 ที่ Server1 และ WS1 ไปเรียก WS2 ที่ Server2 อย่างที่บอกมา
ได้ผลไงจะมาเล่าให้ฟังครับ

  Nine (นาย)  

ผลมาละ

จากการที่ทดสอบ เป็นไปตามที่คาดไว้คือ
 
WS1 มีการใช้ TransactionScope  และภายในมีการเรียกใช้ WS2 อีกครั้งหนึ่ง
หลังจาก ผ่าน method ส่วนที่ Insert Data ไปแล้ว สั่งให้ Throw Exeception ขึ้นเพื่อยกเลิก TX ที่ทำทั้งหมด
 
DB ที่ WS1 ได้ทำการ rollback ออกหมด
แต่ DB ที่ WS2 ไม่สามารถ Rollback ออกได้ 
 
 
Code ที่ใช้ทดสอบ
 
 

// ใช้ TransactionScope

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))

{

 

    //เรียก WS2 เพื่อทำการ Insert Data

    isdmcdev.Service sv = new WSGFSolution.isdmcdev.Service();

    sv.InsertMultiDB(Name, Age, Salary);
 

 

    // ใส่ ServerName เลือก DB Name

    string constrServer2 = @"Server=SQL1;Initial Catalog=TestDB;User Id=sa;password=pass";

    // Insert ลง local DB

    InsertMethod(constrServer1, Name, Age, Salary);

 

    throw new Exception("ยกเลิก TX"); //จุดวาง Breakpoint

 

}

 
 
 
 
จากผลข้างบน พอจะมีทางเลือกอยู่บ้าง
1. ใช้ WS-* ที่ post ไปก่อนหน้านี้ ใช้ใน WS ฝั่งที่มีถูกการอ้างถึง
2. ใช้การควบคุมการ Rollback ค่าใน DB เอาเองโดยใช้ WS เขียนMethod  หากเกิด Error ขึ้นก็สั่งให้ rollback คำสั่ง sql ทั้งหมด
ถ้า update อะไรไปก็ให้ update ค่าเก่ากลับ ลบอะไรไปก็ insert กลับ
3. ใช้ WCF ทดแทน WS ทั้งหมด เพราะมีความสามารถในเรื่องการทำ statefull
 
 

  Nine (นาย)

Asynchronous VS Synchronous อันไหนจะเร็วกว่า ???

Filed under: Computers and Internet — Nine MVP @ 5:25 pm
คือว่าผมได้ทำทดสอบเกี่ยวกับเรื่องความเร็วของ Web Services  ที่มีการเขียน Process ใน Web Services เป็นแบบ Synchronous กับ แบบ Asynchronous
 
แบบ Synchronous
รายละเอียดใน Web Services   สร้าง Connection ให้ 3 Server 
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 1  
รอจนกว่า Server 1 เสร็จ
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 2
รอจนกว่า Server 2 เสร็จ
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 3
รอจนกว่า Server 3 เสร็จ
 
จบการทำ Process Web Services
 
 
แบบ Asynchronous
รายละเอียดใน Web Services   สร้าง Connection ให้ 3 Server 
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 1  
ไม่มีการรอให้ทำ Server1 เสร็จทำ Server2 เลย
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 2 
ไม่มีการรอให้ทำ Server2 เสร็จทำ Server3 เลย
 
คำสั่ง Insert Into Test Values (‘X’) 1000 ครั้ง   ที่  Server 3 
ไม่มีการรอให้ทำ Server3
 
วนลูปรอจนกว่า Server1 , Server2 , Server3 ทำเสร็จจากคำสั่ง .IsComplete
 
ทำเสร็จหมด ก็จบการทำ Process Web Services
 
 
เมื่อเปรียบเทียบเวลาแล้ว  ปรากฏว่า  Synchronous  ดัน  เร็วกว่า Asynchronous 
ซึ่งจริงๆ แล้ว Synchronous น่าจะช้ากว่าด้วยซ้ำ  
 
ผมก็เลยสงสัยว่าจริงๆ แล้ว Asynchronous ดีอย่างไร มาสามารถทำงานได้เร็วกว่าหรือไม่
 
ใครเคยทำการทดสอบเรื่องเวลาการประมวลผล ระหว่าง 2 วิธีนี้บ้าง   รบกวนทีนะครับ
 

DFox
 
 
 

ตอบ :
 
จริง ๆ คุณต้องคิดให้ถูกก่อนนะครับ

การทำงานแบบ Multi-Thread นั้น ใช้ทรัพยากรของเครื่องพอสมควร
ยิ่งคุณแบ่ง Thread ออกมากเท่าไหร่ ทั้ง Memory ทั้ง CPU Time ก็จะถูกแบ่งกระจายออกมาไปมากเท่านั้น
หากงานไม่มีจำนวนมาก ๆ ไม่ได้ใช้เวลาทำงานนานก็ไม่น่าจะใช้งาน Multi-Thread
 
ดังนั้นควรจะใช้ให้ถูกวิธี และลองคิดแบบตั้งสมมติฐาน บนพื้นฐานความจริงกัน บวกกับปัจจัยต่าง ๆ ที่ต้องคำนึงถึง
 
ตัวอย่าง เรากำลังจะเปรียบเทียบ การทำงานแบบเน้นจำนวนงาน เพื่อหาผลลัพธ์ของเวลาที่ทำงานได้ในทั้ง 2 วิธี ต่อไปนี้
 
 
อย่างตัวอย่างของคุณ DFox   เวลาที่ใช้ในแต่ละงานนั้น เป็นเวลาในการทำงานสั้น ๆ จำนวนงานน้อย งานไม่หนัก ไม่ค้างรอผลลัพธ์นาน
 
ถ้างานที่ติดต่อกับ 3 DB แยกกันอยู่ 3 Server
มี 1 task ต่อ 1 DB
มี Process Time ประมาณ 1 วินาที
 
วิธีแบบ synchronous (1 Thread)
    – เวลาที่ใช้ในการ process tasks รวมกันก็ ไม่เกิน 3 วินาที
    – มีการ share memory ด้วยกัน ใช้ environment ของ thread เดียวกัน
    – CPU Time ใช้เต็มที่ 100% ของเวลาที่จัดสรรมาได้จาก OS
 
วิธีแบบ Asynchronous ( 3 Threads)
    – เวลาที่ใช้ในการ Process Tasks รวมกัน ไม่เกิน 1 วินาที
    – เวลาการสร้าง Thread ทั้ง 3 Threads ใช้เวลา x3 เวลา ไม่แน่ใจว่าเท่าไหร่
    – มีการจองเพื่อใช้ Memory เพิ่มขึ้น 1- 2  เท่า ใช้เวลาในการจองพื้นที่ x2 เวลา ไม่แน่ใจว่าเท่าไหร่
    – CPU Time (time slice) ที่ได้มา 100% จะถูกหาร 3 แบ่งเวลาไปให้แต่ละ Thread ใช้ทำงาน 
 
คุณจะเห็นได้ว่าคุณใช้ Asynchronous (Multi-Thread) กับงานนี้ไม่ค่อยเหมาะสมเท่าไหร่
 
 
 
มาลองดูตัวอย่างงานที่ใช้ Asynchronous (Multi-Thread) แล้วน่าจะทำงานได้เหมาะกว่า
 
 
ถ้างานที่ติดต่อกับ 3 DB แยกกันอยู่ 3 Server
มี 20 tasks ต่อ 1 DB
มี Process Time ที่ต้องค้างรอ ต่อ 1 task ประมาณ 5-10 วินาที ( คิดเฉลี่ยที่ 7.5 ละกัน)
 
 
วิธีแบบ synchronous (1 Thread)
    – เวลาที่ใช้ในการ process tasks รวมกันก็ ไม่เกิน 20 tasks  x  3 db x 7.5 วิ = 450 วินาที
    – มีการ share memory ด้วยกัน ใช้ environment ของ thread เดียวกัน
    – CPU Time ใช้เต็มที่ 100% ของเวลาที่จัดสรรมาได้จาก OS
 
วิธีแบบ Asynchronous ( 3 Threads)
    – เวลาที่ใช้ในการ Process Tasks รวมกัน ไม่เกิน 20 tasks x 1(พร้อมกัน) x 7.5 วิ = 150 วินาที

    – เวลาการสร้าง Thread ทั้ง 3 Threads ใช้เวลา x3 ไม่แน่ใจว่าเท่าไหร่
    – มีการจองเพื่อใช้ Memory เพิ่มขึ้น 1- 2  เท่า ใช้เวลาในการจองพื้นที่ x2 เวลา ไม่แน่ใจว่าเท่าไหร่
    – CPU Time (time slice) ที่ได้มา 100% จะถูกหาร 3 แบ่งเวลาไปให้แต่ละ Thread ใช้ทำงาน 

 

จะเห็นได้ว่างานที่มีจำนวนมาก และมีเวลาที่ไม่คงที่ผันเปลี่ยนไปตามค่าปัจจัยต่าง ๆ และมีแนวโน้มว่าจะ long run จริง ๆ แล้ว
ซึ่งคิดว่าน่าจะมีความเหมาะสมที่ใช้ Multi-thread มาช่วยในการทำงาน ซึ่งจะช่วยลดเวลาได้จริงครับ
 
 
 
ยังมีอีกหลายงานที่เราใช้ การทำงานแบบ Asynchronous มาช่วยอีกมากมาย
ทั้งใน User Interface เพื่อแยกการแสดงผล กับ process บางตัวที่ long run เพื่อช่วยให้ มีการตอบสนองการทำงานที่รวดเร็ว ไม่ต้องค้างรอ
เช่น msn รับ msg จากเพื่อนที่คุยมา show ตลอด และเราก็สามารถที่จะคุยโต้ตอบได้ทันทีโดยไม่ต้องรอ เป็นต้น
 
 
ก็ขอให้อ่านทำความเข้าใจ บวกกับทำทดลองให้เกิดความจริง
เพื่อที่จะใช้ technique, feature ของ programming ต่าง ๆ ได้ถูกต้องกับงานครับผม
 
 
ปล. ถ้าว่างเมื่อไหร่จะทำ ตัวอย่างจับเวลามาให้ดูครับ
 

question : เฝ้าระวัง Folder หากมีไฟล์ใดๆ เข้ามาให้โวยวาย. (FlashTaskBar)

Filed under: Computers and Internet — Nine MVP @ 5:21 pm

เฝ้าระวัง Folder หากมีไฟล์ใดๆ เข้ามาให้โวยวาย.

 

 
แนวความคิด
 
              มีโฟล์เดอร์หนึ่ง  (  \\computername\myfolder$\ )  หากมีไฟล์ใดๆเข้ามาที่โฟเดอร์ นี้
ให้โปรแกรมกระพริบ แป๊ป ๆๆๆๆๆ ที่ทากบาร์  (โปรแกรม ICQ ที่มีคนทัก  ครับผม)
ขอตัวอย่างด้วยนะครับ
 
 
——————————————–
 
ขอแสดงความนับถือทุกท่าน

 


Answer : เอา C# code ไปเลยนะ ทำ form กระพริบ

[DllImport("user32.dll")]

static extern Int16 FlashWindowEx(ref FLASHWINFO pwfi);

//Stop flashing. The system restores the window to its original state.

public const UInt32 FLASHW_STOP = 0;

//Flash the window caption.

public const UInt32 FLASHW_CAPTION = 1;

//Flash the taskbar button.

public const UInt32 FLASHW_TRAY = 2;

//Flash both the window caption and taskbar button.

//This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.

public const UInt32 FLASHW_ALL = 3;

//Flash continuously, until the FLASHW_STOP flag is set.

public const UInt32 FLASHW_TIMER = 4;

//Flash continuously until the window comes to the foreground.

public const UInt32 FLASHW_TIMERNOFG = 12;

 

[StructLayout(LayoutKind.Sequential)]

public struct FLASHWINFO

{

    public UInt16 cbSize;

    public IntPtr hwnd;

    public UInt32 dwFlags;

    public UInt16 uCount;

    public UInt32 dwTimeout;

}
 

public static bool FlashWindowEx(IntPtr hWnd)

{

    FLASHWINFO fInfo = new FLASHWINFO();

    fInfo.cbSize = (

ushort)Marshal.SizeOf(fInfo);

    fInfo.hwnd = hWnd;

    fInfo.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG | FLASHW_STOP | FLASHW_TIMER;

    fInfo.uCount =

UInt16.MaxValue;

    fInfo.dwTimeout = 0;

    return (FlashWindowEx(ref fInfo) == 0);

}
 
//เอา method นี้ไปใช้เมื่ออยากให้กระพริบที่ taskbar

private void form_blink()

{

    if (!FlashWindowEx(this.Handle)) { }

}

 
 

  

C# Code การใช้งานตามที่คุณ Jo’ ขอมา
ใช้ FileSystemWatcher + กับ ให้ Blink เตือนเมื่อมีการ Created / Modified / Deleted File ใน ShareFolder ที่ระบุไว้
พร้อมทั้งแจ้งใน show detail ต่าง ๆใน Textbox
 

public Form1()

{

    InitializeComponent();

    initFSW();

}
 

System.IO.FileSystemWatcher fileSystemWatcher1;

 

private void initFSW()

{

    fileSystemWatcher1 = new System.IO.FileSystemWatcher();

    fileSystemWatcher1.Path = "\\\\isdmcdev\\d$\\_Shared";

    fileSystemWatcher1.EnableRaisingEvents = true;

    fileSystemWatcher1.SynchronizingObject = this;

    fileSystemWatcher1.Created += new System.IO.FileSystemEventHandler(fileSystemWatcher1_Created);

    fileSystemWatcher1.Changed += new System.IO.FileSystemEventHandler(fileSystemWatcher1_Changed);

    fileSystemWatcher1.Deleted += new System.IO.FileSystemEventHandler(fileSystemWatcher1_Deleted);

}
 

void fileSystemWatcher1_Deleted(object sender, System.IO.FileSystemEventArgs e)

{

    textBox1.AppendText(e.Name + " deleted.\n");

    if (!FlashWindowEx(this.Handle))

    { }

}
 

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)

{

    textBox1.AppendText(e.Name + " created.\n" );

    if (!FlashWindowEx(this.Handle))

    { }

}
 

private void fileSystemWatcher1_Changed(object sender, System.IO.FileSystemEventArgs e)

{

    textBox1.AppendText(e.Name + " modified.\n");

    if (!FlashWindowEx(this.Handle))

    { }

}


Create a free website or blog at WordPress.com.